码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2020-07-04 22:39:30      阅读:64      评论:0      收藏:0      [点我收藏+]

标签:opera   赋值运算   ace   没有   子类   while   end   nbsp   运算符   

如果一个对象,只是希望他可以被创造出来,不希望被拷贝,那么最先想到的应该是将拷贝和复制运算符私有化:

class A
{
public:
    A(){}
    ~A(){}
private:
    A(const A&){}
    A& operator=(const A&) {}
};

但是书中大师认为,有两类函数仍然可以访问:成员函数和友元函数,如下:

#include<iostream>
using namespace std;
class A
{
public:
    A(){}
    ~A(){}
    friend void MyCopyA_One();
    void MyCopyA_Two()
    {
        A a;
        A b(a);
        b = a;
    }
    private:
    A(const A&){}
    A& operator=(const A&) {}
};
void MyCopyA_One()
{
    A a;
    A b(a);
    b = a;
}
int main()
{
    MyCopyA_One();
    A a;
    a.MyCopyA_Two();
    while (1);
    return 0;
}

 

解决方法是对于私有的拷贝构造函数和赋值运算不定义,那么链接的时候就会因为找不到拷贝或者赋值运算的定义而链接失败,如下:

技术图片

 

 

但是这个错误是在链接的时候才会有的,能不能把错误提前到编译时期,于是大师为我们提供了如下方案:

#include<iostream>
using namespace std;
class Uncopyable
{
public:
    Uncopyable(){}
    ~Uncopyable(){}
private:
    Uncopyable(const Uncopyable&);
    Uncopyable& operator=(const Uncopyable&);
};

class A :private Uncopyable
{
public:
};
int main()
{
    A a;
    //A b(a);  编译不过
    //b = a;   编译不过
    while (1);
    return 0;
}

 

解释:因为子类在调用构造函数时先会调用父类的构造函数,这里由于父类没有定义,所以会编译不过。

 

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

标签:opera   赋值运算   ace   没有   子类   while   end   nbsp   运算符   

原文地址:https://www.cnblogs.com/SunShine-gzw/p/13236730.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!