对Effective条款学习
12。尽量使用初始化而不要在构造函数里赋值
在构造一个类时,对数据成员进行赋值通常有两种方法实现,一种是使用成员初始化列表,一种是在构造函数体内赋值。当然,在很多情况下
选择类似的方法时,看重的不是他的效率问题,更多的是看他的设计需求上。
先来看这个类
template<class t>
class namedptr {
public:
namedptr(const string& initname, t *initptr);
...
private:
const string name;
t *ptr;
};
该类的意图很明显,使得名字和一个t类型的对象指针关联起来。那么在接口上,首先避免类一些不必要的拷贝,防止传入的名字被修改(这更
多是为了语意),因此加上了const和引用;接着在数据成员name上我也不希望别的方法能修改上,加上const修饰。好了现在先扯上语法了,
加了const的数据成员就不得不用初始化了。那么看看const string name有什么功能了,在对接口的的规范化(防止修改,防止拷贝的耗费)
和const关键字,这样就生成了一个其名字成员在类外可以被修改而在内部只是只读对象
事情到这里好象就结束了,不是的,还有一些东西可以学习
大家是否想过如果有多个的数据成员下:
class manydatambrs {
public:
// 缺省构造函数
manydatambrs();
// 拷贝构造函数
manydatambrs(const manydatambrs& x);
private:
int a, b, c, d, e, f, g, h;
double i, j, k, l, m;
};
假如想把所有的int初始化为1而所有的double初始化为0,那么用成员初始化列表就要这样写:因为对于固定数据类型来说,初始和赋值不会有
什么效率上的偏差
manydatambrs::manydatambrs()
: a(1), b(1), c(1), d(1), e(1), f(1), g(1), h(1), i(0),
j(0), k(0), l(0), m(0)
{ ... }
manydatambrs::manydatambrs(const manydatambrs& x)
: a(1), b(1), c(1), d(1), e(1), f(1), g(1), h(1), i(0),
j(0), k(0), l(0), m(0)
{ ... }
这很容易出错,而且不易维护我们这样
void manydatambrs::init()
{
a = b = c = d = e = f = g = h = 1;
i = j = k = l = m = 0;
}
manydatambrs::manydatambrs()
{
init();
...
}
manydatambrs::manydatambrs(const manydatambrs& x)
{
init();
...
}
好了总结下
1 效率上的问题,
2 语意上的问题导致加了限定符不得不使用
12。尽量使用初始化而不要在构造函数里赋值
在构造一个类时,对数据成员进行赋值通常有两种方法实现,一种是使用成员初始化列表,一种是在构造函数体内赋值。当然,在很多情况下
选择类似的方法时,看重的不是他的效率问题,更多的是看他的设计需求上。
先来看这个类
template<class t>
class namedptr {
public:
namedptr(const string& initname, t *initptr);
...
private:
const string name;
t *ptr;
};
该类的意图很明显,使得名字和一个t类型的对象指针关联起来。那么在接口上,首先避免类一些不必要的拷贝,防止传入的名字被修改(这更
多是为了语意),因此加上了const和引用;接着在数据成员name上我也不希望别的方法能修改上,加上const修饰。好了现在先扯上语法了,
加了const的数据成员就不得不用初始化了。那么看看const string name有什么功能了,在对接口的的规范化(防止修改,防止拷贝的耗费)
和const关键字,这样就生成了一个其名字成员在类外可以被修改而在内部只是只读对象
事情到这里好象就结束了,不是的,还有一些东西可以学习
大家是否想过如果有多个的数据成员下:
class manydatambrs {
public:
// 缺省构造函数
manydatambrs();
// 拷贝构造函数
manydatambrs(const manydatambrs& x);
private:
int a, b, c, d, e, f, g, h;
double i, j, k, l, m;
};
假如想把所有的int初始化为1而所有的double初始化为0,那么用成员初始化列表就要这样写:因为对于固定数据类型来说,初始和赋值不会有
什么效率上的偏差
manydatambrs::manydatambrs()
: a(1), b(1), c(1), d(1), e(1), f(1), g(1), h(1), i(0),
j(0), k(0), l(0), m(0)
{ ... }
manydatambrs::manydatambrs(const manydatambrs& x)
: a(1), b(1), c(1), d(1), e(1), f(1), g(1), h(1), i(0),
j(0), k(0), l(0), m(0)
{ ... }
这很容易出错,而且不易维护我们这样
void manydatambrs::init()
{
a = b = c = d = e = f = g = h = 1;
i = j = k = l = m = 0;
}
manydatambrs::manydatambrs()
{
init();
...
}
manydatambrs::manydatambrs(const manydatambrs& x)
{
init();
...
}
好了总结下
1 效率上的问题,
2 语意上的问题导致加了限定符不得不使用