05 :了解C++默默编写并调用哪些函数
空类Empty class,C++处理之后,如果你没有自己声明,编译器就会它声明一个拷贝构造函数,拷贝赋值函数和析构函数,甚至是default构造函数。所有这些函数都是public且inline的。
如果你写了,
class Empty{ };
经过C++处理后相当于:
class Empty{
public:
Empty(){...}; //default构造函数
Empty(const Empty& rhs){..}; //copy构造函数
~Empty(){...}; //析构函数,是否为Virtual?
Empty& operator=(const Empty& rhs){} //copy assignment操作符
}:
惟有当这些函数被需要(被调用),它们才会被编译器创建出来。下面代码造成上述每一个函数被编译器产出:
Empty el; //default构造函数
//析构函数
Empty e2(e1); //copy构造函数
e2 = el; //copy assignment操作符
总结:
编译器暗自为class创建default构造函数,copy构造函数,析构函数和copy assignments操作符。
06: 若不想使用编译器自动生成的函数,就该明确拒绝。
该条款是针对条款05的解决办法!!!
因为条款05已经指出,如果你不声明它们,而某些人尝试调用它们,编译器会为你声明它们。
如果你不声明copy构造函数或copy assignment操作符,编译器可能为你产出一份,于是你的class支持copying。如果你声明它们,你的class还是支持copying。但这里的目标却是要阻止copying!
做法:
-
为了不使用编译器自动提供创建函数的功能,可将相应的成员函数,将
copy构造函数或copy assignment操作符声明为private并且不予实现。 -
使用像
Uncopyable这样的base class也是一种做法。
class HomeForSale {
public:
...
private:
...
HomeForSale (const HomeForsale& ) ; //只有声明
HomeForsale & operator- (const HomeForSale& ) ;
};
有了上述class定义,当客户企图拷贝HomeForSale对象,编译器会阻挠他。如果你不慎在member 函数和friend函数之内那么做,轮到连接器发出抱怨。
一般而言这个做法并不绝对安全,因为member 函数和friend函数还是可以调用你的private函数。除非不去定义它们,那么如果某些人不慎调用任何一个,会获得一个连接错误(linkage error)。
改进方法:
//Uncopyable实现阻止编译器自动创建函数
class Uncopyable{
protected:
Uncopyable(){};
~Uncopyable(){};
private:
Uncopyable(const Uncopyable&); //阻止copy构造函数
Uncopyable& operator=(const Unconpyable&);
}
//为了防止HomeSale对象被拷贝,通过继承Uncopyable类便可以避免
class Homesale: private Uncopyable{
... //class将不再自动声明 copy构造函数以及copy assignment操作符。
...
}
本文揭示了C++中编译器如何隐式创建默认构造函数、拷贝构造函数和析构函数。通过私有化并阻止实现,讲解了如何防止类的复制行为,以及使用Uncopyable基类和继承策略来控制复制。
407

被折叠的 条评论
为什么被折叠?



