使用初始化列表时,基本构造函数未调用两次

时间:2014-04-25 11:54:58

标签: c++ constructor

#include <iostream>

using namespace std;

class Counter
{
protected:
    unsigned int count;
public:
    Counter() : count(0) {cout << "\nCounter Default Constructor";}
    Counter(int i ) : count (i) {cout << "\nCounter Argument Constructor";}

    unsigned int getData ()
    {
        return count;
    }


    Counter operator ++ () // increment (prefix)
    {
        ++count;
        return Counter(count);
    }
};

class inCounter : public Counter
{
public:
    inCounter() : Counter() { cout << "\ninCounter Default Constructor"; }
    inCounter(int c ) : Counter ( c ) {cout << "\ninCounter Argument Constructor";}

    Counter operator -- ()
    {
        --count;
        return Counter ( count ) ;

    }
};

void main ()
{
    inCounter c1(10); }

我期待输出为:

  

计数器参数构造函数

     

inCounter Argument Constructor

     

计数器参数构造函数

但它出来了

  

计数器参数构造函数

     

inCounter Argument Constructor

为什么会这样?

我期望第一个输出的原因是在创建对象c1期间,首先调用基类构造函数,因此打印"Counter Argument Constructor"。然后,调用派生类构造函数,因此打印"inCounter Argument Constructor"。但派生类构造函数再次调用Counter构造函数。因此,"Counter Argument Constructor"应该再次打印。

2 个答案:

答案 0 :(得分:3)

如果通过初始化列表初始化成员,将替换编译器将执行的默认初始化。

这不是一个“附加”调用 - 因为这意味着一个对象被构造了两次。

此外,您可以在案例中使用默认参数来简化操作。这将允许您删除一些不必要的构造函数。

inCounter(int c=0) : Counter (c) 
{
  cout << "\ninCounter Argument Constructor";
}

答案 1 :(得分:0)

我认为您对程序中的以下行感到困惑,

inCounter(int c ) : Counter ( c ) {cout << "\ninCounter Argument Constructor";}

尽管您的代码中有 Counter(c),但它不会两次调用构造函数。而是它 调用下面显示的基类构造函数的参数化版本。

Counter(int i ) : count (i) {cout << "\nCounter Argument Constructor";}

所以正确的输出是,

Counter Argument Constructor

inCounter Argument Constructor