Почему я не могу этого сделать?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
c++
inheritance
amrhassan
источник
источник
Ответы:
Вы не можете инициализировать
a
иb
in,B
потому что они не являются членамиB
. Они являются членамиA
, поэтому толькоA
могут их инициализировать. Вы можете сделать их общедоступными, а затем выполнить присваиваниеB
, но это не рекомендуется, поскольку это разрушит инкапсуляцию. Вместо этого создайте конструктор,A
позволяющийB
(или любому подклассуA
) инициализировать их:источник
a
иb
вB::B()
потому , что они являются частными. Вы не можете инициализировать их, потому что они не являются членамиclass B
. Если вы сделали их общедоступными или защищенными, вы можете назначить их в телеB::B()
.a
иb
...» и изменил его на «Вы не можете инициализировать ...», не убедившись, что остальная часть предложения имеет смысл. Сообщение отредактировано.Оставляя в стороне тот факт, что они есть
private
, посколькуa
иb
являются членамиA
, они предназначены для инициализацииA
конструкторами, а не конструкторами какого-либо другого класса (производными или нет).Пытаться:
источник
Почему-то никто не перечислил самый простой способ:
Вы не можете получить доступ к базовым членам в списке инициализаторов, но сам конструктор, как и любой другой метод-член, может обращаться
public
и кprotected
членам базового класса.источник
B
выделении экземпляра , затем он будет назначен внутриB
конструктора. Но я также думаю, что компилятор все еще может это оптимизировать.class A
мы не можем полагатьсяa
иb
на инициализацию.class C : public A
Например, любая реализация может забыть позвонитьa=0;
и оставитьa
неинициализированным.class A { int a = 0;};
), либо в конструкторе базового класса. Подклассы по-прежнему могут повторно инициализировать их в своем конструкторе по мере необходимости.Это рабочий пример на случай, если вы хотите инициализировать члены данных базового класса, присутствующие в объекте производного класса, в то время как вы хотите передать эти значения, взаимодействуя через вызов конструктора производного класса.
источник
Хотя это полезно в редких случаях (если бы это было не так, язык позволил бы это напрямую), взгляните на идиому Base from Member . Это не решение без кода, вам придется добавить дополнительный уровень наследования, но оно выполняет свою работу. Чтобы избежать шаблонного кода, вы можете использовать реализацию boost
источник
Почему ты не можешь этого сделать? Потому что язык не позволяет вам инициализировать члены базового класса в списке инициализаторов производного класса.
Как это сделать? Как это:
источник
Если вы не укажете видимость для члена класса, по умолчанию она будет закрытой. Вы должны сделать своих участников закрытыми или защищенными, если хотите получить к ним доступ в подклассе.
источник
Совокупные классы, такие как A в вашем примере (*), должны иметь свои члены общедоступные и не иметь определяемых пользователем конструкторов. Они инициализируются списком инициализаторов, например,
A a {0,0};
или в вашем случаеB() : A({0,0}){}
. Члены базового агрегатного класса не могут быть индивидуально инициализированы в конструкторе производного класса.(*) Если быть точным, как было правильно сказано, оригинал
class A
не является агрегатом из-за частных нестатических членовисточник