【问题标题】:Assignment vs Initialization in C++C ++中的赋值与初始化
【发布时间】:2011-01-19 04:09:12
【问题描述】:

我认为构造函数控制初始化,而 operator= 函数控制 C++ 中的赋值。那么为什么这段代码有效呢?

#include <iostream>
#include <cmath>
using namespace std;

class Deg {
    public:
        Deg() {}
        Deg(int a) : d(a) {}        
        void operator()(double a)
        {
            cout << pow(a,d) << endl;
        }

    private:
        int d;
};

int
main(int argc, char **argv) 
{
    Deg d = 2;
    d(5);
    d = 3; /* this shouldn't work, Deg doesn't have an operator= that takes an int */
    d(5);
    return 0;
}

在主函数的第三行,我将int 分配给Deg 类的对象。由于我没有operator=(int) 函数,我认为这肯定会失败……但它调用了Deg(int a) 构造函数。那么构造函数也控制赋值吗?

【问题讨论】:

    标签: c++ class initialization operator-overloading


    【解决方案1】:

    这就是所谓的隐式类型转换。编译器将查看是否有一个构造函数可以直接从您分配的类型更改为您尝试分配的类型,然后调用它。您可以通过在您不希望被隐式调用的构造函数前面添加 explicit 关键字来阻止它发生,如下所示:

    explicit Deg(int a) : d(a) {}

    【讨论】:

    • 我工作过的至少一家公司在其编码标准中规定了“在所有构造函数上使用显式,除非有充分的理由不这样做”的规则。这有助于避免此类可能令人费解的情况。
    • 我想你的意思是所有可以用单个参数调用的构造函数:) ?
    • “一个很好的理由不[使用显式]”在用于多参数 ctor 时会造成不必要的混淆。
    【解决方案2】:

    只是为了澄清 JonM 的回答:

    对于d = 3 行,涉及一个赋值运算符。正如 JonM 所说,3 被隐式转换为 Deg,然后使用编译器生成的赋值运算符将 Deg 赋值d(默认情况下,它是一个成员明智的分配)。如果你想阻止赋值,你必须声明一个私有赋值运算符(并且不要实现它):

    //...
    private:
        Deg& operator=(const Deg&);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 2014-05-25
      相关资源
      最近更新 更多