代码之家  ›  专栏  ›  技术社区  ›  lava

C++构造函数调用

c++
  •  3
  • lava  · 技术社区  · 15 年前

    我用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
    
    3 回复  |  直到 11 年前
        1
  •  11
  •   Arpegius    15 年前

    您刚刚调用复制构造函数的代码,定义如下:

    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;
    
        2
  •  15
  •   Khaled Alshaya    15 年前
    ABC a = b;
    

    这是 复制构造函数 不是分配运算符!您可以这样重新定义它,您拥有的是编译器生成的:

    ABC(const ABC& other)
    {
     c = other.c;
     cout << c << " copy constructor" << endl;
    }
    

    如果您真的坚持不使用复制构造函数,那么您可以向类中添加转换运算符,而忽略复制构造函数!

    operator char()
    {
      return c;
    }
    
        3
  •  0
  •   Tunvir Rahman Tusher    11 年前

    看看你修改过的代码

    #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
    

    现在让我们解释一下为什么 在3种情况下调用复制构造函数 1.初始化中的对象时 2.将对象作为参数传递给函数时 3.从函数返回对象时。

    如果不指定自己的复制构造函数,编译器将实现自己的复制构造函数,该构造函数逐位复制对象。您没有指定自己的复制构造函数,因此无法跟踪从代码创建的两个对象。 谢谢