通过对item5的学习我们知道:编译器会暗自为class创建default构造函数、copy构造函数、copy assignment操作符以及析构函数。
but,有时候我们不希望我们的类有某些特定功能,通常的做法就是不声明具有这些功能的函数就可以了,however,对于某些与生俱来的功能——比如copy构造和copy assignment,即使我们不声明,系统也会自动生成。
解决办法是可以在类中声明copy构造函数和copy assignment操作符,但并不实现这些函数,并将其声明为private,这样就可以阻止编译器自动生成默认函数,又可以阻止别人调用这些功能。
编译的时候就会报出“error C2248: “HomeForSale::HomeForSale”: 无法访问 private 成员(在“HomeForSale”类中声明)”这样的错误!
根据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的,无法调用,所以相互矛盾。
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的,无法调用,所以相互矛盾。