Чому я не можу цього зробити?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Чому я не можу цього зробити?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Відповіді:
Ви не можете форматувати 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.
{
}
};
a
і b
в B::B()
тому , що вони є приватними. Ви не можете їх ініціалізувати, оскільки вони не є членами class B
. Якщо ви зробили їх публічними чи захищеними, ви можете призначити їх у органі B::B()
.
a
та b
..." і змінив її на "Не можете ініціалізувати ...", не впевнившись, що решта речення мала сенс. Публікація відредагована.
Залишаючи в стороні той факт , що вони private
, так a
і b
є членами A
, вони покликані бути инициализирован A
конструкторами «S, що не конструкторами якого - то іншого класу (похідний чи ні).
Спробуйте:
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) {}
};
Якось ніхто не перераховував найпростіший спосіб:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
Ви не можете отримати доступ базових елементів в списку ініціалізації, але сам конструктор, так само , як і будь-який інший метод члена, може отримати доступ public
і protected
членів базового класу.
B
виділяється екземпляр , а потім буде призначений всередині B
конструктора 's. Але я також думаю, що компілятор може все-таки це оптимізувати.
class A
ми не можемо покладатися на a
і b
ініціалізації. class C : public A
Наприклад, будь-яка реалізація , можливо, забуде дзвонити a=0;
та залишати a
неініціалізованою.
class A { int a = 0;};
), або в конструкторі базового класу. Підкласи все ще можуть повторно ініціалізувати їх у своєму конструкторі за потребою.
# 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;
}
Це робочий приклад у випадку, якщо ви хочете ініціалізувати членів базового класу даних, присутніх у об’єкті «Похідний клас», тоді як ви хочете, щоб ці значення переплетені через виклик конструктора «Похідний клас».
Хоча це корисно у рідкісних випадках (якби це не було, мова дозволила б це прямо), подивіться на Базу з ідіоми учасника . Це не рішення для коду, вам доведеться додати додатковий рівень успадкування, але це робить роботу. Щоб уникнути кодового коду, ви можете скористатися реалізацією boost
Чому ти не можеш це зробити? Оскільки мова не дозволяє ініціалізувати членів базового класу у списку ініціалізаторів похідного класу.
Як ви можете це зробити? Подобається це:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
Якщо ви не вказали видимість для члена класу, він за замовчуванням буде "приватний". Ви повинні зробити своїх членів приватними або захищеними, якщо ви хочете отримати доступ до них у підкласі.
Зведені класи, як A у вашому прикладі (*), повинні мати своїх членів загальнодоступними та не мати визначених користувачем конструкторів. Вони ініціалізуються зі списком ініціалізатора, наприклад, A a {0,0};
або у вашому випадку B() : A({0,0}){}
. Члени базового агрегованого класу не можуть бути індивідуально ініціалізовані в конструкторі похідного класу.
(*) Якщо бути точним, як це було правильно сказано, оригінал class A
не є сукупністю через приватні нестатичні члени