C++构造函数调用

3

我用C++编写了这个小代码片段,输出也一并附上。但是我不明白为什么构造函数只被调用了一次,而析构函数却被调用了两次。

据我所知,应该在第28行调用默认构造函数和重载赋值运算符。

能否请有经验的开发者来解释一下:

  1 #include <iostream>
  2 using namespace std;
  3 
  4 class ABC {
  5   char c;
  6   public:
  7     ABC() {
  8       cout << "default" << endl;
  9     }
 10     ABC(char c) {
 11       this->c = c;
 12       cout << c << endl;
 13     }
 14     ~ABC() {
 15       cout << hex << this << " destructor " << c << endl;
 16     }
 17     void method() {
 18       cout << "method" << endl;
 19     }
 20     void operator= (const ABC& a) {
 21       cout << "operator" << endl;
 22     }
 23
 24 };
 25 
 26 int main() {
 27   ABC b('b');
 28   ABC a = b;
 29 }

Output in g++ version 4.0.1:
~/src$ g++ test.cpp
~/src$ ./a.out 
b
0xbffff0ee destructor b
0xbffff0ef destructor b

构造函数标签有什么问题吗? - GManNickG
3个回答

15
ABC a = b;

这是复制构造函数,而不是赋值运算符!你可以像这样重新定义它,你所拥有的是编译器生成的构造函数:

ABC(const ABC& other)
{
 c = other.c;
 cout << c << " copy constructor" << endl;
}
如果你真的坚持不使用复制构造函数,你可以向你的类添加转换运算符并忘记复制构造函数!
operator char()
{
  return c;
}

更好的方法是,您可以使用初始化列表。 - anon
是的,就目前而言,在你的代码中,复制构造函数包含对 c 的赋值运算符的调用。 - Johannes Schaub - litb
请确保不要使用类型转换运算符,我只是出于好玩才提到它,这并不适用于此情况 :) - Khaled Alshaya

11
你刚刚调用了复制构造函数,这是它的定义:
ABC(const ABC& a):c(a.c){
    cout << "copying " << hex << &a << endl;
}

你应该会看到这样的输出:

b
copying 0x7fffebc0e02f
0x7fffebc0e02e destructor b
0x7fffebc0e02f destructor b

如果你想调用默认构造函数并且再调用赋值运算符,那么你必须使用两条独立的语句:

  ABC b('b');
  ABC a;
  a = b;

0
请看一下您修改后的代码。
#include <iostream>
using namespace std;
class ABC {
    char c;
public:

    ABC() {
        cout << "default" << endl;
    }
        ABC(char c)
        {
            cout<<"parameterized constructor called\n";/////overloaded constructor called for the first line in main
            this->c = c;
            cout << c << endl;
        }
        ABC(ABC &c)
        {
            cout<<"Copy cons\n";//copy constructor is called for the second line in main
        }


        ~ABC() {
            cout << hex << this << " destructor " << c << endl;
        }
        void method() {
            cout << "method" << endl;
        }
        void operator= (const ABC& a) {

        }


    };


int main()
{
        ABC b('b');//////here parameterized constructor is called i.e <ABC(char c)>
        ABC a = b;/////////Here the copy constructor is called not the default one.(total 2 object created so the destructor is called twice!)
}

程序的输出是:
parameterized constructor called
b
Copy cons
0x7fff5fbff820 destructor �
0x7fff5fbff828 destructor b

现在让我们解释一下为什么复制构造函数会在三种情况下被调用: 1. 当对象被初始化时 2. 当对象作为参数传递给函数时 3. 当对象从函数中返回时
如果您没有指定自己的复制构造函数,那么编译器将实现其自己的复制构造函数,该函数按位复制对象。由于您没有指定自己的复制构造函数,因此无法跟踪从代码创建的两个对象。 谢谢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接