наследование c ++ и конструкторы - PullRequest
3 голосов
/ 21 января 2011
class A {
public:
      A(int i): data(i) {cout << "A::A(" << i << ")" << endl;}
      A(const char* s): data(0) { cout << "A::A(" << s << ")"<< endl;}
      ~A() { cout << "A::~A()" << endl;}
private:
int data;
};

class B:public A {
public:
    B(const A& a): A(a){ std::cout << "B::B(const A& a)" << std::endl;}
     ~B() { std::cout << "B::~B()" << std::endl;}
};

int main() {
    B b0(0);
    B b1("abc");
return 0;
}

Довольно просто, может кто-нибудь объяснить, почему вывод:

 A::A(0)
 B::B(const A& a)
 A::~A()
 A::A(abc)
 B::B(const A& a)
 A::~A()
 B::~B()
 A::~A()
 B::~B()
 A::~A()

Ответы [ 6 ]

5 голосов
/ 21 января 2011

B b0(0); - такого конструктора для B нет, поэтому компилятор ищет какой-то конструктор, который можно вызвать только одним приведением (одно неявное приведение разрешено, 2 - нет), поэтому он находит B::B(const A& a),потому что A имеет конструктор только с одним параметром, а это A::A(int i).Это означает, что 0 можно привести к int, поэтому временный объект A создается (и уничтожается после создания B).Итак, вот почему у нас есть


 A::A(0)
 B::B(const A& a)
 A::~A()

Тогда следующее называется: B b1("abc");, вот так:


 A::A(abc)
 B::B(const A& a)
 A::~A()

Это абсолютно то же самое, что и с int, ноздесь с char*.

Затем оба объекта разрушаются, поэтому их деструкторы вызываются в обратном порядке, как и их конструкторы, вот откуда


 B::~B()
 A::~A()
 B::~B()
 A::~A()

.1021 *

Выглядит заманчиво, потому что вы не перегружены A::A( const A& a) и не видите, что он тоже вызывается 2 раза.

Приветствия (:


Небольшое редактирование: не A::A(), а A::A( const A& a) - благодаря Ним.

3 голосов
/ 21 января 2011

У вас нет конструктора по умолчанию для B, поэтому компилятор находит лучшие альтернативы (т.е. сначала строит A с соответствующими входными данными, а затем конструирует B из этого.)

последовательность будет:

  • построить временную A с int
  • построить B с этим A
  • уничтожить это A
  • (у вас нет конструктора копирования для A, иначе вы бы тоже его там добавили!)
  • то же самое для строки
  • , затем последовательность базового класса/ производные деструкторы классов.
1 голос
/ 21 января 2011
 1.  A::A(0)          <- temporary A in B b0(0) line
 2.  B::B(const A& a) <- construct b0, no visible call to A as you did not provide A(A const &)
 3.  A::~A()          <- destroy temporary A created in line 1        
 4.  A::A(abc)        <- temporary A in B b1("abc") line
 5.  B::B(const A& a) <- construct b1, no visible call to A as you did not provide A(A const &)
 6.  A::~A()          <- destroy temporary A created in line 4
 7.  B::~B()          <- b1 ~B() destructor
 8.  A::~A()          <- b1 ~A() destructor
 9.  B::~B()          <- b0 ~B() destructor
 10. A::~A()          <- b0 ~A() destructor
1 голос
/ 21 января 2011

Создает временный A с аргументом в конструкторе B, который он использует для инициализации B :: A (через конструктор копирования по умолчанию - следовательно, нет вывода для A :: A (const A &)).вызов B :: B завершен.

1 голос
/ 21 января 2011

Создается временный объект A, который затем передается через константную ссылку в конструктор B, где он копируется с использованием копии ctor (которую вы не дополнили выводом отладки, поэтому вы не можете увидеть это) в B объект.

Уничтожение происходит в обратном порядке строительства; Временные работы уничтожаются, когда конструктор, которому они были переданы, заканчивается.

0 голосов
/ 21 января 2011

попробую:

 A::A(0)          // 1: construct an A using A(int) ctor in line 1 of main
 B::B(const A& a) // 2: construct a B passing the previously constructed A by const ref
 A::~A()          // 3: destruct the temporary A made in 1
 A::A(abc)        // 4:  construct an A using A(const char*) ctor in line 2 of main
 B::B(const A& a) // 5: construct a B passing the previously constructed A by const ref
 A::~A()          // 6: destruct the temporary A made in 4
                  // unwind the stack on exit of main
 B::~B()          // destruct B made in main line 2
 A::~A()          // destruct A inherited by B made in main line 2
 B::~B()          // destruct B made in main line 1
 A::~A()          // destruct A inherited by B made in main line 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...