copy构造函数是一个尤其重要的构造函数,因为它定义了一个对象如何pass by value(以值传递)。
例如:
bool hasAcceptQualit(Widget w);
Wiget w1;
if(hasAcceptQuality(w1))
{
}
它定义了参数W是以by value(以值传递)的方式传递给hasAcceptQuality。所以在上述调用中,w1被复制到w体内,这个copy操作由Widget的复制构造函数完成。pass by value传递用户自定义类型是一个比较坏的主意,没有pass by reference好!
今天读到55页,日行一善,日积月累!
有些情况即使面对的成员变量属于内置类型,也一定得使用初值列。是的,如果成员是const或references,它们就一定需要初值,不能被赋值。
为免除跨编译单元,使用local static代替non local static!
如果某编译单元内的某个非局部静态对象的初始化动作使用了另一编译单元内的某个非局部静态对象,它所用到的这个对象可能尚未被初始化。因为C++对“定义于不同编译单元内的非局部静态对象”的初始化次序无明确定义。
class Directory
{
public:
Directory(params);
...
};
Directory::Directory(params)
{
...
std::size_t disks = tfs.numDisks();
...
}
进一步假设,这些客户决定创建一个Directory对象,用来放置临时文件:Directory temoDir(params);//为临时文件而做出的目录
现在初始化次序的重要性显现出来了,除非tfs在tempDir之前先被初始化,否则tempDir的构造函数会用到尚未初始化的tfs。但tfs和tempDir是不同的人在不同的时间于不同的源码文件建立起来的,它们是定义于不同编译单元内的非局部静态对象,如何确定tfs会在tempDir之前被初始化?
相对困难,这里试试一个小小的设计可完全消除这个问题,需要做的是:将每个非局部静态对象搬到自己的专属函数内,该对象在此函数内被声明为static。这些函数返回一个引用指向它所含的对象,然后用户调用这些函数,而不之家指涉这些对象。换句话说,非局部静态对象被局部静态对象替换了。设计模式的粉丝们想必认出来了,这是单例模式的一个常见实现手法。
改为:class FileSystem{...};
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
class Directory{...};
Directory::Directory(params)
{
...
std::size_t disks = tfs().numDisks();
....
}
Directory& temoDir()
{
static Directory td;
return td;
}为免除“跨编译单元之初始化次序”问题,请以loacl static对象替换non-loacl static对象。
为驳回编译器自动提供的机能,可将相应的成员函数声明为private并且不予实现。使用uncopyable这样的base class也是一种做法。复制构造函数,赋值构造函数等。。。
析构函数别产生异常,可以使用try catch来捕获。
令 class& operator=返回一个*this即当前对象。
当你编写一个copying函数,请确保(1)复制所以局部成员变量(2)调用所有基类内的适当的copying函数。
不要尝试以某个copying函数实现另一个copying函数。应该将共同机能放进第三个函数中,并由两个coopying函数共同调用。
阅读到93页了!
许多资源被动态分配于heap内而后被用于单一区块或函数内。它们应该在控制流离开那个区块或函数时被释放。标准程序库提供的auto_ptr正是针对这种形势而设计的特制产品。auto_ptr是个“类指针”对象,也就是所谓的"智能指针",其析构函数自动对其所指对象调用delete。
void f()
{
std::auto_ptr<Investment> pInv(createInvestment());//调用factory函数,一如既往的使用pInv,经由auto_ptr的析构函数自动删除pInv
......
}
其实使用trl::share_ptr<>要比auto_ptr好,因为后者复制操作的时候对象会变为null。而前者不会,复制操作比较明显。
}
他们都提供了一个Get成员函数,用来执行显示转换,也就是它会返回智能指针内部的原始指针。
看到110页!
尽量以pass-by-reference-to -const替换pass-by-value。前者通常比较高效,并可避免切割问题。并不适用于内置类型以及STL的迭代器和函数对象,对他们而言,pass-by-value往往比较适当。
看到182页!