Использование членов объекта до его создания

У меня есть следующий простой код:

#include <iostream>
#include <vector>

template <class Derived>
struct Base
{
Base()
{
static_cast<Derived*>(this)->foo();
}

std::vector<int> m_ints;
};

struct Derived : Base<Derived>
{
Derived() : Base()
{
std::cout << a;
}

void foo()
{
m_ints.push_back(37);
a = 4;
}

int a;
};

int main()
{
Derived d;
return 0;
}

Я знаю о порядке вызова конструкторов при создании объекта. Конструктор вызывается из «самого базового -> вниз». Поэтому в конструкторе Base производный объект не полностью построен.

1) Безопасно ли звонить Derived::foo в Base конструктор, когда Derived::foo не трогай Derived объект? Я имею в виду, когда нет такой строки, как a = 4, просто касаясь Base объект.

2) Если я запускаю опубликованный код, он действительно работает, хотя я касаюсь a который не должен существовать в то время. Это гарантия на работу? (Я проверил это на VS2013, VS2010 и GCC 4.8.1 на Ideone)

1

Решение

Это будет работать в этом конкретном случае, но я бы посоветовал не делать этого.
Незаметные изменения в коде могут внезапно нарушить логику (например, кто-то делает метод foo виртуальным, кто-то инициализирует элемент данных a в конструкторе или Derived, …).

Если базовый класс нуждается в информации из производного класса, то производный класс должен передать эту информацию конструктору базового класса. В этом классе значение 37 должно быть передано из конструктора Derived в конструктор Base.

И когда элемент данных a должен быть инициализирован, инициализируйте его в конструкторе Derived, а не где-нибудь еще.

РЕДАКТИРОВАТЬ: В C ++ 11, если класс Derived хочет внедрить код в конструктор Base, он может передавать лямбду в Base. Затем Base просто выполняет лямбду в своем конструкторе.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]