为什么构造函数被调用了两次 [英] Why constructor is being called twice

查看:344
本文介绍了为什么构造函数被调用了两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白构造函数的工作?



这里我已声明一个对象 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 from abc(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆