使用STL会降低程序可读性??
今天头一次自己做一个大模块。
我图方便,循环使用了for_each 和 bind 组合起来用,因为我实在讨厌写迭代器的声明;模块内部为了方便内存管理我都是使用了智能指针,然后typedef成一个XXXPtr的类型;而且也没有使用项目组里广泛使用的map,而是使用了unordered_map,因为我觉得能提高性能。
今天评审代码,说我的代码到处都是STL,可读性很差。“要是我读这个代码,肯定读不明白。”
我对说这话的同事印象还挺好的,人很聪明,而且能看的进去别人的代码。很多老旧的模块他都能看懂。
为啥他这样说呢?
STL真的会破坏可读性么?
[解决办法]
不能这么说吧。越是复杂,自然越要花功夫去读。
[解决办法]
他不懂stl而已。
当然,也不排除你stl使用上确实不标准。
[解决办法]
不会破坏可读性,读不明白是基础问题。。
[解决办法]
模块边界清楚不就行了。仅仅“到处都是STL”都能拿来当“可读性差”的堂皇的借口,八成说明读代码的水平太低,只是找不到个上台面的说法罢了。(虽然没看过LZ的代码也不能排除滥用或者有其它问题。)
只是懒得写迭代器类型,auto也就算了。
bind看你怎么用。
智能指针也一样,该用unique_ptr的地方不要用shared_ptr。
unordered_map是不是比map性能好,看需要什么操作。
[解决办法]
//比较简洁,速度可能比较慢
void CPP_SOLUTION_ONE()
{
std::ifstream inFile("before.txt");
std::vector<double> data( ( std::istream_iterator<double>(inFile) ), std::istream_iterator<double>() );
std::sort(std::begin(data), std::end(data) );
std::ofstream outFile("after.txt");
std::copy(std::begin(data), std::end(data), std::ostream_iterator<double>(outFile, "\n") );
}
//比较烦杂,速度可能比较快
void CPP_SOLUTION_TWO()
{
FILE *fin = fopen("before.txt", "r");
std::vector<double> data;
double number = 0;
while( fscanf(fin, "%lf", &number) == 1 ) data.push_back(number);
fclose(fin);
std::sort(std::begin(data), std::end(data) );
std::ofstream outFile("after.txt");
std::copy(std::begin(data), std::end(data), std::ostream_iterator<double>(outFile, "\n") );
}
#include<stdlib.h>
#include<stdio.h>
int compare(void const *p, void const *q)
{
double p0 = *(double*)p;
double q0 = *(double*)q;
if(p0 > q0) return 1;
else if(p0 < q0) return -1;
return 0;
}
void quit()
{
fprintf(stderr, "memory exhausted\n");
exit(1);
}
void C_SOLUTION()
{
int res = 1000; //initial allocation
double *buf = (double*)malloc(sizeof(double) * res);
if(buf == 0) quit();
int n = 0; //number of elements
int i = 0;
FILE *fin = fopen("before.txt", "rt");
double d;
while( fscanf(fin, "%lf", &d) == 1 )
{
if(n == res)
{
res += res;
buf = (double*)realloc(buf, sizeof(double) * res );
if(buf == 0) quit();
}
buf[n++] = d;
}
fclose(fin);
qsort(buf, n, sizeof(double), compare);
FILE *fout = fopen("after.txt", "wt");
for(i = 0; i != n; ++i) fprintf(fout, "%f\n", buf[i]);
fclose(fout);
free(buf);
}
someObject *a = new someObject;
//do something and throw some exception
delete a;
//throw exception
b= new someObject;
}
~someClass() { delete a; delete b;}
};
[/code]
construct的动作还没完成,就抛出exception了
这种时候destructor根本不会执行,资源无法被释放
还有另外一种很常见的使用状况就是锁和解锁
[code]
std::mutex lk;
void mfunction(){
lk.lock()
//do something and throw exception
lk.unlock(); //永远不会被解锁
}
[/code]
这会造成dead lock
我不喜欢exception,但是exception是c++的一部分
就算我不喜欢他也必须妥善的处理eception
以上的情况,除了RAII外,在c++中还有更好的方法解决吗?
不善用RAII就得到处加try...catch,程式更难维护
这是各c++的大牛大力推荐smart pointer(RAII)的理由之一
请问如果你有比RAII更好的方法吗?
[解决办法]
美化一下
class someClass{
public :
someClass()
{
a = new someObject;
//throw exception
b= new someObject;
}
~someClass() { delete a; delete b;}
private:
someObject *a;
someObject *b;
};
std::mutex lk;
void mfunction(){
lk.lock()
//do something and throw exception
lk.unlock(); //永远不会被解锁
}
vector<shared_ptr<string>> weird_codes;
这也是RAII
A::iterator end = A.end();
for(A::iterator it = A.begin(); it != end; ++it){...}
for(auto const &data : input){
...}
A::iterator begin = A.begin();
A::iterator end = A.end();
for(it = begin; it != end; ++it){...}