《Effect C++》学习------条款06:若不想使用编译器自动生成的函数,就该明确拒绝
2016-08-14 14:52
351 查看
举个例子:地产中介商卖的是房子,有这样一个类:
每个房子都是不一样的,所以希望这样:
我们希望最后这两句话不能通过编译,那么怎样在C++中实现呢?
一种想当然的做法,就是不去写拷贝构造函数和赋值运算符。但由上一个条款可以知道,这样做是行不通的,C++编译器会我们生成四个默认的成员函数,其中就有拷贝构造函数和赋值运算符,所以不写是不能解决问题的。如果写了呢?这确实是一个突破口,自己写了成员函数,编译器就不会生成默认的了,但不能写在public里,因为public的函数都是可以在外部被调用的,一种好的方法就将这些函数写在private或者protected里面,大概像这样:
但是这个做法并不是绝对安全的,因为member函数和friend函数还是可以调用你的private函数,除非你不去定义他们(只是声明他们),但是这样会获得一个连接错误(linker error)。”将成员函数声明为private函数,而不去实现他们”这一伎俩是大家可以接受的,在C++ iostream程序库中就有这样的应用。就像下来的例子:
这样即使通过编译,链接器也会报错的,因为只有声明而没有具体的实现。那现在回过头来问一下,能不能不要搞特殊,直接把拷贝构造函数和赋值运算符声明在public下,只是不要实现之?
这种方法是可以的,因为链接器不会放过这个只有声明的空架子,但这不是一种好的解决方法。因为有这样一个编程的原则:错误越早被发现就越好。编译要早于链接,所以在编译发现错误要优于在链接阶段才发现的错误,可以节省时间,提高效率。
这样HomeForSale就不能被拷贝了。这里的继承可以不是public,比如private。
不过注意:C++11增加了
[x] 为了驳回编译器自动提供的机能(比如可拷贝),可将相应的成员函数声明为private且不予实现。还有一种方法,继承Uncopyable也行。
class HomeForSale
{…}
每个房子都是不一样的,所以希望这样:
HomeForSale house1; HomeForSale house2; HomeForSale house3(house1); // house3企图与house1相同,不能通过这种情况 house2 = house1; // house2也不应该与house1相同,也不能通过这种情况
我们希望最后这两句话不能通过编译,那么怎样在C++中实现呢?
一种想当然的做法,就是不去写拷贝构造函数和赋值运算符。但由上一个条款可以知道,这样做是行不通的,C++编译器会我们生成四个默认的成员函数,其中就有拷贝构造函数和赋值运算符,所以不写是不能解决问题的。如果写了呢?这确实是一个突破口,自己写了成员函数,编译器就不会生成默认的了,但不能写在public里,因为public的函数都是可以在外部被调用的,一种好的方法就将这些函数写在private或者protected里面,大概像这样:
class HomeForSale { private: HomeForSale(const HomeForSale& house){...} HomeForSale& operator= (const HomeForSale& house){...} };
但是这个做法并不是绝对安全的,因为member函数和friend函数还是可以调用你的private函数,除非你不去定义他们(只是声明他们),但是这样会获得一个连接错误(linker error)。”将成员函数声明为private函数,而不去实现他们”这一伎俩是大家可以接受的,在C++ iostream程序库中就有这样的应用。就像下来的例子:
class HomeForSale { private: HomeForSale(const HomeForSale&); HomeForSale& operator= (const HomeForSale&); };
这样即使通过编译,链接器也会报错的,因为只有声明而没有具体的实现。那现在回过头来问一下,能不能不要搞特殊,直接把拷贝构造函数和赋值运算符声明在public下,只是不要实现之?
这种方法是可以的,因为链接器不会放过这个只有声明的空架子,但这不是一种好的解决方法。因为有这样一个编程的原则:错误越早被发现就越好。编译要早于链接,所以在编译发现错误要优于在链接阶段才发现的错误,可以节省时间,提高效率。
class Uncopyable { protected: Uncopyable(){} ~Uncopyable(){} private: Uncopyable(const Uncopyable&); Uncopyable& operator= (const Uncopyable&); }; class HomeForSale: public Uncopyable {…};
这样HomeForSale就不能被拷贝了。这里的继承可以不是public,比如private。
不过注意:C++11增加了
function() = delete;这样的简单用法,意为告诉编译器不自动产生这个函数。
[x] 为了驳回编译器自动提供的机能(比如可拷贝),可将相应的成员函数声明为private且不予实现。还有一种方法,继承Uncopyable也行。
相关文章推荐
- Effective C++学习笔记 条款06:如不想使用编译器自动生成的函数,就该明确拒绝
- 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- Effective C++ -----条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- 《Effective C++》学习笔记条款06 若不想使用编译器自动生成的函数,就该明确拒绝
- 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- Effective C++ 条款06 若不想使用编译器自动生成的函数,就该明确拒绝
- 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- 条款06 若不想使用编译器自动生成的函数 就该明确拒绝
- Effective C++:条款06:若不想使用编译器自动生成的函数,就该明确拒绝。
- Effective C++_笔记_条款06_若不想使用编译器自动生成的函数,就该明确拒绝
- 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- 条款06: 若不想使用编译器自动生成的函数,就该明确拒绝
- [Effective C++]条款06 若不想使用编译器自动生成的函数,就该明确拒绝
- Effective C++ 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- Effective C++ 条款06 若不想使用编译器自动生成的函数,就该明确拒绝
- 读书笔记《Effective C++》条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- [Effective C++读书笔记]006_条款06_若不想使用编译器自动生成的函数,就该明确拒绝