8 ответов:
вы не можете инициализировать
aиbнаBпотому что они не являются членамиB. Они являются членамиA, поэтому толькоAможет их инициализировать. Вы можете сделать их общедоступными, а затем выполнить задание вB, но это не рекомендуется, так как это разрушит инкапсуляцию. Вместо этого, создайте конструктор вAразрешитьB(или любой подклассA) для их инициализации:class A { protected: A(int a, int b) : a(a), b(b) {} // Accessible to derived classes // Change "protected" to "public" to allow others to instantiate A. private: int a, b; // Keep these variables private in A }; class B : public A { public: B() : A(0, 0) // Calls A's constructor, initializing a and b in A to 0. { } };
оставляя в стороне тот факт, что они являются
privateСaиbчленыA, они должны быть инициализированыAконструкторы, а не конструкторы какого-либо другого класса (производные или нет).попробуй:
class A { int a, b; protected: // or public: A(int a, int b): a(a), b(b) {} } class B : public A { B() : A(0, 0) {} }
хотя это полезно в редких случаях (если бы это было не так, язык позволил бы это напрямую), взгляните на база из идиомы члена. Это не бесплатное решение для кода, вам нужно будет добавить дополнительный уровень наследования, но он выполняет свою работу. Чтобы избежать шаблонного кода, Вы можете использовать реализация boost
# include<stdio.h> # include<iostream> # include<conio.h> using namespace std; class Base{ public: Base(int i, float f, double d): i(i), f(f), d(d) { } virtual void Show()=0; protected: int i; float f; double d; }; class Derived: public Base{ public: Derived(int i, float f, double d): Base( i, f, d) { } void Show() { cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl; } }; int main(){ Base * b = new Derived(10, 1.2, 3.89); b->Show(); return 0; }это рабочий пример в случае, если вы хотите инициализировать элементы данных базового класса, присутствующие в объекте производного класса, тогда как вы хотите передать эти значения, взаимодействующие с помощью вызова конструктора производного класса.
почему вы не можете это сделать? Потому что язык не позволяет инициализировать базовый класс "члены в списке инициализаторов производного класса".
Как вы можете это сделать? Вот так:
class A { public: A(int a, int b) : a_(a), b_(b) {}; int a_, b_; }; class B : public A { public: B() : A(0,0) { } };
почему-то никто не перечислил самый простой способ:
class A { public: int a, b; }; class B : public A { B() { a = 0; b = 0; } };вы не можете получить доступ к базовым элементам в списке инициализаторов, но сам конструктор, как и любой другой метод элемента, может получить доступ
publicиprotectedчлены базового класса.
Если вы не указываете видимость для члена класса, по умолчанию он имеет значение "private". Вы должны сделать ваши члены частными или защищенными, если вы хотите получить к ним доступ в подклассе.
агрегатные классы, как и в вашем примере (*), должны иметь свои члены открытыми и не иметь пользовательских конструкторов. Они инициализируются с помощью списка инициализаторов, например
A a {0,0};или в вашем случаеB() : A({0,0}){}. Члены базового агрегатного класса не могут быть индивидуально инициализированы в конструкторе производного класса.(*)если быть точным, как правильно было сказано, оригинал
class Aне является агрегатом из-за частных нестатических членов
Comments