我的问题是最后一句话,即在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
答案 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)
可用作从int
到Test
的转化运算符。评估b = 100
时,100将转换为Test
,并且会调用默认赋值运算符。
答案 2 :(得分:0)
执行b=100
时,基本上发生的是编译器生成b.operator=(Test(100))
您看到的构造函数调用来自Test(100)
。
如果您创建构造函数explicit
,则编译器无法使用构造函数将int
值隐式转换为Test
对象,并且您将收到错误。
答案 3 :(得分:-1)
我不确定,但是,
我开始知道编译器首先搜索匹配函数调用..
B = 100;
即。 overloaded assignment operator function
为class A
,其中int为参数
当它找不到任何合适的匹配时,它会将调用指向参数化构造函数。
反过来完成剩下的任务。
如果我错了或者我在这里遗漏了任何细节,请随意填写。