[英]Why Paramaterized constructor called when assignment is happening?
My question is for the last statement ie before return 0;
我的问题是最后一条语句,即return 0;
之前return 0;
Why the parametrize constructor is being called when we are trying to assign an int value to an object. 当我们尝试为对象分配int值时,为什么要调用参数构造函数。
My piece of code: 我的一段代码:
#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;
}
OUTPUT: 输出:
param ctor: 0
param ctor: 5
param ctor: 100
The reason is simple: every class X
has a copy constructor (a consturctor taking X
) and a copy assignment operator (an assignment operator taking X
). 原因很简单: 每个类X
都有一个副本构造函数(构造函数采用X
)和一个副本赋值运算符(一个采用X
的赋值运算符)。 If you don't declare these yourself, the compiler declares them for you implicitly. 如果您自己没有声明它们,则编译器将为您隐式声明它们。 In some cases, they are defined as deleted (which means it is an error to use them), but they're always there. 在某些情况下,它们被定义为已删除(这意味着使用它们是错误的),但是它们始终存在。
So when you do this: 因此,当您执行此操作时:
b = 100;
it's effectively translated to this: 它被有效地翻译为:
b.operator=(100)
and the best matching overload of operator=
is searched for. 并搜索operator=
的最佳匹配重载。 There's only one overload, actually: the implicitly declared copy-assignment operator Test& Test::operator=(const Test &)
, so the compiler checks if it could convert the argument 100
to the assignment operator's parameter type const Test &
. 实际上只有一个重载:隐式声明的副本分配运算符Test& Test::operator=(const Test &)
,因此编译器检查是否可以将参数100
转换为赋值运算符的参数类型const Test &
。 And it turns out that it can, thanks to the converting constructor Test::Test(int)
, so that is what ends up called. 事实证明,这要归功于转换构造函数Test::Test(int)
,所以最终被调用。
If you want to disable such behaviour, you can mark the constructor as explicit
. 如果要禁用这种行为,可以将构造函数标记为explicit
。 This will prevent it from being used for implicit conversions, such as the one converting 100
to the type of the assignment operator's parameter. 这将防止它用于隐式转换,例如将100
转换为赋值运算符的参数类型的隐式转换。
Your constructor Test(int s=0)
can be used as a conversion operator from int
to Test
. 您的构造函数Test(int s=0)
可以用作从int
到Test
的转换运算符。 When b = 100
is evaluated, 100 is converted to Test
, and than default assignment operator is invoked. 当计算b = 100
,会将100转换为Test
,然后调用默认的赋值运算符。
When you do b=100
what basically happens is that the compiler generates b.operator=(Test(100))
当您执行b=100
,基本上发生的是编译器生成b.operator=(Test(100))
The constructor call you see is from that Test(100)
. 您看到的构造函数调用来自该Test(100)
。
If you make the constructor explicit
then the compiler can't use the constructor to implicitly convert int
values to Test
objects, and you would get an error. 如果使构造函数explicit
则编译器将无法使用构造函数将int
值隐式转换为Test
对象,并且会出现错误。
I am not sure on this but, 我对此不确定,但是,
I came to know that compiler first searches for the matching function call for.. 我知道编译器首先搜索匹配的函数。
b=100; b = 100;
ie an overloaded assignment operator function
for class A
which takes int as parameter and when It fails to find any suitable match it directs the call to parametrize constructor. 例如, class A
的overloaded assignment operator function
,将int作为参数,当它找不到任何合适的匹配项时,会将调用定向到参数构造函数。
which in turn do the rest of the assignment job. 依次完成其余的分配工作。
Please fill free to correct me if I am wrong or if I am missing any detail here. 如果我错了或者我在这里错过了任何细节,请自由地纠正我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.