为什么在赋值发生时调用了Paramaterized构造函数?

时间:2016-03-10 14:41:54

标签: c++ copy-constructor assignment-operator

我的问题是最后一句话,即在return 0;

之前

为什么在我们尝试将int值赋给对象时调用参数化构造函数。

我的代码:

#include<iostream>
using namespace std;
class Test {
private:
    int i;
    public:
    Test(int s=0):i(s) {
            cout<<"param ctor: "<<i<<endl;
    }
};

int main()
{
    Test a;         //param ctor called
    Test b(5);      //param ctor called
    //b(a);         //error as we have not implemented copy ctor
    b=a;            //compiler provided assignment opr. called
    b=100;          //why param ctor called for this.??
    return 0;
}

输出:

  param ctor: 0
  param ctor: 5
  param ctor: 100

4 个答案:

答案 0 :(得分:7)

原因很简单:每个X都有一个复制构造函数(一个带有X的构造函数)和一个复制赋值运算符(赋值运算符{{1} })。如果您不自己声明这些,则编译器会隐式声明它们。在某些情况下,它们被定义为已删除(这意味着使用它们是错误的),但它们始终存在。

所以当你这样做时:

X

它有效地转化为:

b = 100;

搜索b.operator=(100) 的最佳匹配重载。实际上只有一个重载:隐式声明的复制赋值运算符operator=,因此编译器会检查它是否可以将参数Test& Test::operator=(const Test &)转换为赋值运算符的参数类型100。事实证明,由于转换构造函数const Test &,它可以最终调用。

如果要禁用此类行为,可以将构造函数标记为Test::Test(int)。这将阻止它用于隐式转换,例如将explicit转换为赋值运算符参数类型的转换。

答案 1 :(得分:0)

您的构造函数Test(int s=0)可用作从intTest的转化运算符。评估b = 100时,100将转换为Test,并且会调用默认赋值运算符。

答案 2 :(得分:0)

执行b=100时,基本上发生的是编译器生成b.operator=(Test(100))

您看到的构造函数调用来自Test(100)

如果您创建构造函数explicit,则编译器无法使用构造函数将int值隐式转换为Test对象,并且您将收到错误。

答案 3 :(得分:-1)

我不确定,但是,

我开始知道编译器首先搜索匹配函数调用..

  

B = 100;

即。 overloaded assignment operator functionclass A,其中int为参数 当它找不到任何合适的匹配时,它会将调用指向参数化构造函数。

反过来完成剩下的任务。

如果我错了或者我在这里遗漏了任何细节,请随意填写。