zoukankan      html  css  js  c++  java
  • 第五篇:明确拒绝不想编译器自动生成的拷贝构造函数和赋值运算符重载函数

    前言

           如果你不想要编译器帮你自动生成的拷贝机制 (参考前文),那么你应当明确的拒绝。

           如何拒绝?这便是本文要解决的主要问题。

    问题描述

           当你定义了一个类,而这个类中各对象之间也是封装的 - 禁止同类对象之间的相互赋值以及复制,那么你需要屏蔽掉编译器帮你生成的拷贝构造函数以及赋值运算符。

           在许多代码中,会看到通过将拷贝构造函数和赋值运算符重载函数声明为私有且不予实现来实现这个功能。然而,这不是最科学的做法。

           因为这没有做到真正的屏蔽:你在自己的成员函数中,或者友元函数中仍然可以调用这两个私有函数,编译器将不会报错。

           也许你会狡辩,这种做法的私有拷贝构造函数以及赋值运算符重载函数都没有实现,编译器会报错。但,报错的不是编译器,是链接器。优质的代码应当将错误尽可能的移至编译期。

    科学的做法

           首先专门为阻止拷贝动作设计一个类,如下:

    1 class Uncopyable {
    2 protected:
    3     Uncopyable() {}    // 允许派生类对象构造,析构。
    4     ~Uncopyable() {}
    5 private:
    6     Uncopyable(const Uncopyable &);    // 但阻止拷贝
    7     Uncopyable& operator=(const Uncopyable &);
    8 };

           如果你需要屏蔽掉某个类的拷贝机制,需要做的只是私有继承该类:

    1 1 class A : private Uncopyable {
    2 2     //......
    3 3 };

           类 A 的拷贝函数被顺利屏蔽掉了。当 A 类对象发生拷贝或赋值,必然会先去执行其父类 Uncopyable 类的拷贝构造函数或重载赋值运算符函数。但这两个函数在 Uncopyable 中已经被声明为私有了,因此编译器会不通过。

    小结

           这种做法的科学依据在于,目标类的成员函数或者友元函数也都无法调用被屏蔽的拷贝构造函数和赋值运算符重载函数。

           如果调用发生,报错的也是编译器,而非链接器。

  • 相关阅读:
    AD域服务器的部署 【1】— AD域介绍
    Docker 设置http代理
    在Django中将SQLite3数据库迁移到MySQL
    pycharm远程更新代码到远端服务器
    这个看着更好。Docker中使用MySQL
    docker换成最好用的源
    docker基础命令
    在docker中运行mysql实例
    centos7安装mysql
    centos 7 修改ip
  • 原文地址:https://www.cnblogs.com/muchen/p/6353739.html
Copyright © 2011-2022 走看看