Передача константной ссылки по цепочке конструкторов - PullRequest
2 голосов
/ 21 июня 2011

Я получаю ошибку времени выполнения со следующим кодом:

</p>

<code>#include <iostream>

using namespace std;

class A {
    int n;

public:
    A();
    A(const int k);
    int getn() const { return n; };
};

A::A() : n(0) {};

A::A(const int k) : n(k) {}

class B {
    const A& myA;

public:
    B(const A& anA);
    int getn() const { return myA.getn(); };
};

B::B(const A& anA) : myA(anA) {}

class C {
    const A& myA;
    const B& myB;

public:
    C(const A& anA);
    int getn() const { return myB.getn(); };
};

C::C(const A& anA) : myA(anA), myB(myA) {}

class D {
    A myA;
    C myC;

public:
    D(const int k);
    int getAn() const { return myA.getn(); };
    int getCn() const { return myC.getn(); };
};

D::D(const int k) : myA(k), myC(myA) {}

int main() {
    D myD(10);
    cerr << "A: " << myD.getAn() << '\n';
    cerr << "C: " << myD.getCn() << '\n';
}
</code>

Я либо получаю ошибку сегментации во второй строке вывода, либо "C: 0", вместо "C: 10", которую я ожидаю

Ответы [ 2 ]

12 голосов
/ 21 июня 2011

Проблема в этой строке: C::C(const A& anA) : myA(anA), myB(myA) {}
myB является ссылкой. А к чему? Ответ на временный. myB(myA) создаст временный объект, назначенный вашей ссылке. К сожалению, этот объект будет уничтожен после выхода из Ctor.
Измените свой код на следующий:

class C {
const A& myA;
const B myB;

public:...

и должно работать.

Кстати: я почти всегда объявляю конструкторы с одним аргументом как явные. Сделайте это, и компилятор предупредит вас.

0 голосов
/ 21 июня 2011

Вы пытаетесь инициализировать D :: myC со ссылкой на D :: myA, это не правильно, потому что объект не полностью построен в данный момент.

D::D(const int k) : myA(k), myC(myA) {}
...