通过对item5的学习我们知道:编译器会暗自为class创建default构造函数、copy构造函数、copy assignment操作符以及析构函数。
but,有时候我们不希望我们的类有某些特定功能,通常的做法就是不声明具有这些功能的函数就可以了,however,对于某些与生俱来的功能——比如copy构造和copy assignment,即使我们不声明,系统也会自动生成。
解决办法是可以在类中声明copy构造函数和copy assignment操作符,但并不实现这些函数,并将其声明为private,这样就可以阻止编译器自动生成默认函数,又可以阻止别人调用这些功能。
例如:
// PrivateConstructor.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class HomeForSale
{
private:
HomeForSale(const HomeForSale&); //声明一个copy构造函数,并不实现它,连变量名字都没有起
HomeForSale& operator=(const HomeForSale&); //声明一个copy assignment操作符,并不实现它
double price;
double area;
public:
HomeForSale(double price, double area):price(price),area(area){}
};
int _tmain(int argc, _TCHAR* argv[])
{
HomeForSale home(1000, 2000);
HomeForSale home1(home); //error:无法访问 private 成员(在“HomeForSale”类中声明)
HomeForSale home2 = home;//error:无法访问 private 成员(在“HomeForSale”类中声明)
return 0;
}
编译的时候就会报出“error C2248: “HomeForSale::HomeForSale”: 无法访问 private 成员(在“HomeForSale”类中声明)”这样的错误!
有了这样的声明(而不是定义),当客户企图拷贝HomeForSale对象时,编译器就会阻止他,如果不慎在类的其他成员函数或者friend函数中做了这样的事,就会出现link error。
以下方法可以将连接错误移至编译期:
// PrivateConstructor.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class Uncopyable
{
protected:
Uncopyable(){}
~Uncopyable(){}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
class HomeForSale: private Uncopyable
{
private:
double price;
double area;
public:
HomeForSale(double price, double area):price(price),area(area){}
};
int _tmain(int argc, _TCHAR* argv[])
{
HomeForSale home(1000, 2000);
//HomeForSale home1(home); //error:无法访问 private 成员(在“HomeForSale”类中声明)
//HomeForSale home2 = home;//error:无法访问 private 成员(在“HomeForSale”类中声明)
return 0;
}
根据item5我们知道:如果某个base class将copy assignment操作符声明为private,编译器将拒绝为其derived classes生成一个copy assignment操作符,因为如果生成了,那么derived classes中的copy assignment操作符就必须能够调用base class中的copy assignment操作符进行处理继承下来的base class中的成员,而base class中的copy assignment操作符被声明成了private的,无法调用,所以相互矛盾。
分享到:
相关推荐
一、前言 在前面一篇文章中(https://blog.csdn.net/qq_41453285/article/details/104165762),我们介绍了C++编译器...如果我们不想使用某些函数,将这些不想使用的函数在类中声明为private,那么就不能使用这些函数了
条款06:若不想使用编译器自动成生的函数,就该明确拒绝 条款07:为多态基类声明Virtual析构函数 条款08:别让异常逃离析构函数 条款09:绝不在构造和析构过程中调用Virtual函数 条款10:令Operator=返回一个...
条款27:如果不想使用隐式生成的函数要显示的禁止它 条款28:划分全局名字空间 4、类和函数:实现 条款29:避免返回内部数据的句柄 条款30:避免这样的成员函数,其返回值是指向成员的非CONST指针或引用 条款31:千万不要...
只有深刻了解 C++ 编译器如何解释你的码,你才有可能以 C++ 语言写出稳健强固的软体。本书是协助你获得此等层级之了解过程中,一份极具价值的资源。读过本书之後,我感觉像是浏览了 C++ 程式大师所检阅过的码,并...
一些经过验证的用来改善程序效率的方法,包括检验C++语言特性所带来的时间和空间上的成本。 全面地描述了C++专家所使用的高级技术,包括...如果你的编译器不支持这些特性,本书还介绍了如何不利用它们完成工作。
条款27: 如果不想使用隐式生成的函数就要显式地禁止它 条款28: 划分全局名字空间 第五章 类和函数: 实现 条款29: 避免返回内部数据的句柄 条款30: 避免这样的成员函数:其返回值是指向成员的非const指针或引用,但...
条款06:若不想使用编译器自动生成的函数,就该明确拒绝 explicitly disallow the use of compiler-generated functions you do not want. 条款07:为多态基类声明virtual析构函数 declare destructors virtual in ...
一些经过验证的用来改善程序效率的方法,包括检验C++语言特性所带来的时间和空间上的成本。, 全面地描述了C++专家所使用的高级技术,包括...如果你的编译器不支持这些特性,本书还介绍了如何不利用它们完成工作。
条款06:如不想使用编译器自动生成的函数,就应该明确拒绝 为了驳回编译器暗自提供的机能,可将相应的成员函数声明为private并且不予实现。使用像Uncopyable这样的base class 也是一种做法。不过C++11开始,可以用...
C++ 为类(Class)提供了许多默认函数。如果自己没有申明,编译器会为我们提供一个copy构造函数、一个copy assignment操作符和一个析构...就像Effective C++说的,如果不想使用编译器自动生成的函数,就应该明确拒绝。 1
<br>《Effective STL》目录: <br>前言 致谢 导读 容器 条款1:仔细选择你的容器 条款2:小心对“容器无关代码”的幻想 条款3:使容器里对象的拷贝操作轻量而正确 条款4:用empty来代替...
条款6: 警惕C++的及其令人恼怒的分析 条款7: 当使用new得指针的容器时,切记在容器销毁前delete那些指针 条款8: 千万不要把auto_ptr放入容器中 条款9: 小心选择删除选项 条款10: 当心allocator的协定和约束 ...
条款32:如果你真的想删除东西的话就在类似remove的算法后接上erase 条款33:提防在指针的容器上使用类似remove的算法 条款34:注意哪个算法需要有序区间 条款35:通过mismatch或lexicographical比较实现简单的...
我们在前面文章已经介绍了,如果类没有手动声明拷贝构造函数或拷贝赋值运算符,那么编译器会为我们自动生成这两个成员,并且它们的行为是:将被拷贝的对象的所有成员做一份拷贝 二、复制对象时确保复制所有成员 下面...
条款6: 警惕C++的及其令人恼怒的分析 条款7: 当使用new得指针的容器时,切记在容器销毁前delete那些指针 条款8: 千万不要把auto_ptr放入容器中 条款9: 小心选择删除选项 条款10: 当心allocator的协定和约束 ...
Windows平台下也有好多人都喜欢用SourceInsight编辑C/C++程序,如果将pclint集成到SourceInsight中,那就相当于给SourceInsight增加了一个C/C++编译器,而且它的检查更严格,能发现一些编译器发现不了的问题,可以...
这是一个比Josh Bloch的Effective Java规则更精妙的10条Java编码实践的列表。和Josh Bloch的列表容易学习并且关注日常情况相比,这个列表将包含涉及API/SPI设计中不常见的情况,可能有很大影响。 我在编写和维护...
此仓库是我围绕Scott Meyers的“ Effective Modern C ++”进行的动手实践培训。 每个项目都涵盖了一个我发现很重要的主题,我想尝试一下。 大部分代码是原始代码,但是,还有一些其他网站示例中的复制粘贴,例如...