您的位置:首页 > 其它

条款06:若不想使用编译器自动生成的函数,就该明确拒绝.

2009-06-05 10:23 288 查看
条款06:若不想使用编译器自动生成的函数,就该明确拒绝.
(Explicitly disallow the use of compiler-generated functions
you do not want)

内容:
在条款05中,我们弄清楚了编译器为我们自动生成的函数,而在现
实中,我们有时并不需要编译器为我们提供某些函数的实现,因为它们
的出现会导致我们现实中的某些最基本的常识变的不合理,违背事物
发展的基本规律和准则,显然这些都不是我们想要的.那怎么办?最好
的办法就是让编译器去拒绝这种特定的机能,具体如何做呢?
比如举个例子,某一公司里面的员工类Employee,你立刻会写下如
下类似实现:
class Employee{
public:
Employee(){}
Employee(int id,const string& name,...)
:id_(id),name_(name),...{
}
...
private:
int id_;
string name_;
...
};
//test.cpp
Employee employee1(60015207,"scofieldzhu",...);
Employee employee2(60012345,"xiaohewang",...);
Employee employee3(employee1); //legal? Line1:
Employee employee4;
employee4 = employee2; //legal? Line2:
仔细思考Line1,Line2的代码,这样写合法么?Employee对象在公司
里面应该是唯一的(absolute ID),不能对它进行拷贝构造和赋值操作,
你应该很乐意看到编译器拒绝这个操作,而不幸的是这里编译器编译却
通过了,为什么呢?就是我们上一款提到的编译器自动这个类提供了默
认的拷贝构造和赋值运算,我们如何让编译器去阻止拷贝和赋值操作呢
?我们这里提出了一种现在很常用的做法:去声明它们而不去实现它,编
译器声明的函数都是public,而为了阻止编译器去暗自创建专属版本,
你可以将这些函数声明为private,这样就阻止了编译器去调用它(外部
对象不能访问私有成员函数).好,那么上面类可以这样去声明了:
class Employee{
public:
Employee(){}
Employee(int id,const string& name,...)
:id_(id),name_(name),...{
}
...
private:
Employee(const Employee&);
Employee& operator = (const Employee&);
int id_;
string name_;
...
};
重新编译一下test.cpp,喔霍,compiler error:cannot access
private member declared in class 'Employee'.我们可以再次进行
优化一下完全可以写一个基类去完成类似功能:
class Uncopyable{
protected:
Uncopyable(){} //only derived can generator object
~Uncopyable(){}
private:
Uncopyable(const Uncopyable&); //prevent copy
Uncopyable& operator = (const Uncopyable&); //prevent '='
};
我只要继承给类就可以了:
class Empolyee:private Uncopyable{
public:
...
};
这样写完全可以行得通,任何尝试拷贝构造和赋值运算(包括成员
函数和友元函数)的访问,编译器会尝试生成对应的操作,它就必须调
用基类对应的copy and assign copy操作,而基类的操作是私有成员,
编译器调用就会被拒绝,呵呵,不错的想法吧!这里Empolyee为什么要
用private继承而不用我们习惯的public继承,要解释原因就超出我们
今天要讨论的话题了,以后条款中我会详细给你介绍它们的.

请记住:
■ 为驳回编译器自动(暗自)提供的机能,可将相应的成员函数声明
为private并且不予实现.使用像Uncopyable这样的base class也是一
种做法.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐