为什么构造函数被调用了两次 [英] Why constructor is being called twice
问题描述
我不明白构造函数的工作?
这里我已声明一个对象 obj2
。它调用构造函数 abc()
,这是完全正常。
但是当我分配< b
$ b
obj2 = 100
为什么编译器允许将整数初始化为类对象?如果它是允许的,那么它是如何破坏对象,然后如何调用另一个参数化构造函数。
现在我有另一个问题,为什么 destructor
只被调用一次,因为 / code>对象?
还有一个疑问,编译器 code> default constructor
那么为什么默认构造函数必需
?
class abc {
public:
int a,b;
abc()
{a = 0; b = 0;}
abc(int x)
{a = x;}
〜abc()
{std :: cout ;& Destructor Called\\\
;}
};
int main()
{
abc obj1;
cout<< OBJ1<< obj1.a<< ...< obj1.b<< \\\
;
abc obj2;
cout<< OBJ2< obj2.a<< ...< obj2.b<< \\\
;
obj2 = 100;
cout<< OBJ2< obj2.a<< \\\
;
system(pause);
return 0;
}
/ p>
OBJ1 0 ... 0
OBJ2 0 ... 0
析构函数调用
OBJ2 100
让我们玩show and tell,让我们全部特殊成员:
#include< iostream>
class abc {
public:
int a,b;
abc()
{std :: cout< Default constructor\\\
; a = 0; b = 0;}
abc(int x)
{std :: cout< Int constructor\\\
; a = x;}
abc(abc const& other):a(other.a),b(other.b)
{std :: cout< Copy constructor(<< a<<,<< b<<)\\\
; }
abc& operator =(abc const& other){
std :: cout< 赋值运算符(<< a<<,<< b< .b < - )\ n;
a = other.a;
b = other.b;
return * this;
}
〜abc()
{std :: cout< Destructor Called\\\
;}
};
int main()
{
abc obj1;
std :: cout<< OBJ1<< obj1.a<< ...< obj1.b<< \\\
;
abc obj2;
std :: cout<< OBJ2< obj2.a<< ...< obj2.b<< \\\
;
obj2 = 100;
std :: cout<< OBJ2< obj2.a<< \\\
;
return 0;
}
我们获得此输出:
默认构造函数
OBJ1 0 ... 0
默认构造函数
OBJ2 0 ... 0
Int构造函数
赋值运算符(0,0)=(100,0)
析构函数
OBJ2 100
析构函数调用
析构函数调用
来源:
int main()
{
abc obj1;
//默认构造函数
std :: cout<< OBJ1<< obj1.a<< ...< obj1.b<< \\\
;
// OBJ1 0 ... 0
abc obj2;
//默认构造函数
std :: cout<< OBJ2< obj2.a<< ...< obj2.b<< \\\
;
// OBJ2 0 ... 0
obj2 = 100;
// Int构造函数
//赋值运算符(0,0)=(100,0)
//析构函数调用
std :: cout< ; OBJ2< obj2.a<< \\\
;
// OBJ2 100
return 0;
//析构函数调用
//析构函数调用
}
第一个惊喜:尽管 obj2
稍后更改值 abc obj2;
仍会在声明点调用默认构造函数。
第二个惊喜: obj2 = 100
实际上是指 obj2.operator =(abc(100));
,即:
- 从
abc(100)
abc > - 将其分配给
obj2
- 在继续执行下一条语句之前销毁临时
第三个惊喜:析构函数在范围结束时调用,紧靠括号 code>(和是,
return
之后)。因为你使用系统(暂停)
我假设你在Windows =>虽然运气,他们在调用结束暂停后,因此您的控制台窗口消失在眨眼的眼睛在他们会出现的那一刻。您可以从更为永久的控制台启动程序,也可以使用额外的范围:
int main(){
{
//您的代码在这里
}
系统(pause);
return 0;
}
I do not understand how constructors work
?
Here I have declared an object obj2
. It calls constructor abc()
, which is perfectly fine.
But when I am assigning
obj2 = 100
Why does compiler allow initializing an integer to a class object? If at all it is allowing then how it is destroying the object and then how it is calling another parameterized constructor.
Now I have another question why destructor
is called only once as there are two
objects?
One more doubt I have is, compiler is not doing anything
with default constructor
then why default constructor is required
?
class abc{
public:
int a, b;
abc()
{a = 0; b = 0;}
abc(int x)
{a = x;}
~abc()
{std::cout << "Destructor Called\n";}
};
int main()
{
abc obj1;
cout << "OBJ1 " << obj1.a << "..." << obj1.b << "\n";
abc obj2;
cout << "OBJ2 " << obj2.a << "..." << obj2.b << "\n";
obj2 = 100;
cout << "OBJ2 " << obj2.a << "\n";
system("pause");
return 0;
}
output:
OBJ1 0...0
OBJ2 0...0
Destructor Called
OBJ2 100
Let us play show and tell, so let us instrument all special members:
#include <iostream>
class abc{
public:
int a, b;
abc()
{ std::cout << "Default constructor\n"; a = 0; b = 0;}
abc(int x)
{ std::cout << "Int constructor\n"; a = x;}
abc(abc const& other): a(other.a), b(other.b)
{ std::cout << "Copy constructor (" << a << ", " << b << ")\n"; }
abc& operator=(abc const& other) {
std::cout << "Assignment operator (" << a << ", " << b << ") = (" << other.a << ", " << other.b << ")\n";
a = other.a;
b = other.b;
return *this;
}
~abc()
{std::cout << "Destructor Called\n";}
};
int main()
{
abc obj1;
std::cout << "OBJ1 " << obj1.a << "..." << obj1.b << "\n";
abc obj2;
std::cout << "OBJ2 " << obj2.a << "..." << obj2.b << "\n";
obj2 = 100;
std::cout << "OBJ2 " << obj2.a << "\n";
return 0;
}
And we obtain this output:
Default constructor
OBJ1 0...0
Default constructor
OBJ2 0...0
Int constructor
Assignment operator (0, 0) = (100, 0)
Destructor Called
OBJ2 100
Destructor Called
Destructor Called
So, let's reconcile them with line sources:
int main()
{
abc obj1;
// Default constructor
std::cout << "OBJ1 " << obj1.a << "..." << obj1.b << "\n";
// OBJ1 0...0
abc obj2;
// Default constructor
std::cout << "OBJ2 " << obj2.a << "..." << obj2.b << "\n";
// OBJ2 0...0
obj2 = 100;
// Int constructor
// Assignment operator (0, 0) = (100, 0)
// Destructor Called
std::cout << "OBJ2 " << obj2.a << "\n";
// OBJ2 100
return 0;
// Destructor Called
// Destructor Called
}
You mostly had it all, let us examine the surprises.
First surprise: even though obj2
changes value later abc obj2;
will still call the default constructor at the point of declaration.
Second surprise: obj2 = 100
actually means obj2.operator=(abc(100));
, that is:
- Build a temporary (unnamed)
abc
fromabc(100)
- Assign it to
obj2
- Destroy the temporary before moving on to the next statement
Third surprise: destructors are called at the end of the scope, right before the closing bracket }
(and yes, after the return
). Since you are using system("pause")
I assume you are on Windows => though luck they are called after you end the pause and thus your console Windows disappears in the blink of an eye at the moment they would have appeared. You can either launch the program from a more permanent console, or use an extra scope:
int main () {
{
// your code here
}
system("pause");
return 0;
}
这篇关于为什么构造函数被调用了两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!