是否应该在赋值时调用构造函数?

时间:2016-11-07 01:49:11

标签: c++

VS2015中以下代码的输出是“构造函数”。

由于缺少赋值运算符,它不应该无法编译吗?

struct A { };

struct B {
    B(){}
    B(const A& a) {
        cout << "constructor" << endl;
    }

    //B& operator=(const A& a) {
    //  cout << "assignment operator" << endl;
    //  return *this;
    //}
};

int main() {
    A a;
    B b;
    b = a;

    return 0;
}

3 个答案:

答案 0 :(得分:30)

是的,当转换正在进行时,就像在测试用例中一样。

您正在有效地致电

b = B(a);

因为隐式声明了B的赋值运算符B& operator=(B const&),所以在重载解析期间会找到它。由于您的作业只是一次转换,而不是匹配(这恰好是允许发生的转化次数),因此会将a转换为B,然后分配新的临时B } b

答案 1 :(得分:14)

让我们考虑一个类似的例子。

double a;
int b=5;

a=b;

您可以分配给double的唯一内容是另一个double。但是,int可以转换为double

同样在这里,A可以转换为B,因为这样做的构造函数存在。这就是发生的事情。

答案 2 :(得分:11)

您的代码已从if(fileName.trim().contains(" ")) fileName.replace(" ","_"); 隐式转换为AB编译为b = a。如果您希望将其检测为错误,可以使用the explicit specifier

b = B(a);

然后您应该收到错误,例如these generated by ideone.com

struct B {
    B(){}
    explicit B(const A& a) {
        std::cout << "constructor" << std::endl;
    }
};

之后,永远不会隐式调用构造函数,如果要调用它,则必须明确地编写它:prog.cpp: In function 'int main()': prog.cpp:20:7: error: no match for 'operator=' (operand types are 'B' and 'A') b = a; ^ prog.cpp:5:8: note: candidate: B& B::operator=(const B&) struct B { ^ prog.cpp:5:8: note: no known conversion for argument 1 from 'A' to 'const B&' prog.cpp:5:8: note: candidate: B& B::operator=(B&&) prog.cpp:5:8: note: no known conversion for argument 1 from 'A' to 'B&&'