zoukankan      html  css  js  c++  java
  • Effective C++(5) 了解C++默默地编写并调用哪些函数

    预热:

    一个空的类,当编译器处理过之后,就包含:
    • 一个copy构造函数
    • 一个重载赋值操作符
    • 一个析构函数
    • 一个默认构造函数
    Demo:

    class Empty()  {   };       // 声明一个空的类
    
    class Empty()     // 经过编译器处理后
    {
    public:
        Empty() { ... }
        Empty(const Empty& rhs) { ... }
        ~Empty() { ... }
    
        Empty& operator=(const Empty& rhs) { ... }
    };


    需要注意的一点是,只有当这些函数被需要时,它们才会被编译器创建出来。

    现在我们知道了,编译器会为我们创建这些函数。
    下面举个例子引入今天的重点问题
    如果编译器拒绝为我们做这些事情了,就麻烦了。那么,编译器什么情况下会拒绝为我们做这些事情呢?

    Demo:

    class Empty()  {   };       // 声明一个空的类
    
    class Empty()     // 经过编译器处理后
    {
    public:
        Empty() { ... }
        Empty(const Empty& rhs) { ... }
        ~Empty() { ... }
    
        Empty& operator=(const Empty& rhs) { ... }
    };
     


    类NameObject并没有给我们重载赋值操作符,哪门这个编译器会给我提供这个操作吗,如果提供了这个操作,那么Demo中的p最后的成员的值是什么呢?让我们慢慢来分析一下:
    1 p.nameValue
    C++规定:不可以让reference改指向不同的对象。
    因此,C++对这种情况是拒绝编译这一行的赋值动作。即如果你打算在一个有reference成员的class内支持重载赋值操作,那么你必须自己定义重载赋值操作符。
    2 p.objectValue
    对于const成员变量,更改const变量是不合法的,所以编译器同样拒绝为你创建这个赋值操作。
    3 还有一个情况会导致编译器“罢工”
    如果某个base classes将重载赋值操作符声明为private。
    原因:子类中的重载赋值操作符会默认去调用基类中的赋值操作符。

    小结:
    编译器可以暗自为你创建默认构造函数、拷贝构造函数、重载赋值操作符,以及析构函数。
    但是需要注意那些编译器拒绝你的情况。

    参考:
    《Effective C++ 3rd》

  • 相关阅读:
    聊聊ASP.NET Core默认提供的这个跨平台的服务器——KestrelServer[转]
    java的war包和jar包的区别
    shell编程中的表达式(-d, -f, -L 等)
    nginx 403 forbidden
    docker删除镜像
    TCP的拥塞控制
    文件从暂存区撤销
    charles修改返回结果的4种方法
    LED 正负极区分
    病毒传播模拟游戏制作日志(三)
  • 原文地址:https://www.cnblogs.com/suzhou/p/3638968.html
Copyright © 2011-2022 走看看