Ответ 1
да защищенные члены доступны производными классами, но вы обращаетесь к нему в функции main(), которая находится за пределами иерархии. Если вы объявите метод в классе B и получите доступ к нему, это будет нормально.
Я не делал С++ через некоторое время и не могу понять, почему следующее не работает:
class A {
protected:
int num;
};
class B : public A {
};
main () {
B * bclass = new B ();
bclass->num = 1;
}
Компиляция:
ошибка C2248: "A:: num": не может получить доступ к защищенному члену, объявленному в классе "A"
Не должны ли защищенные члены быть доступными по производным классам?
Что мне не хватает?
да защищенные члены доступны производными классами, но вы обращаетесь к нему в функции main(), которая находится за пределами иерархии. Если вы объявите метод в классе B и получите доступ к нему, это будет нормально.
Да, защищенные члены доступны производному классу, но только изнутри класса.
Пример:
#include <iostream>
class A {
protected:
int num;
};
class B : public A { public:
void printNum(){
std::cout << num << std::endl;
}
};
main () {
B * bclass = new B ();
bclass->printNum();
}
выведет значение num
, но num
получает доступ из класса B
. num
должен быть объявлен открытым, чтобы иметь доступ к нему как bclass->num
.
Он доступен в рамках функций B, но вы пытаетесь получить к нему доступ в основном.
Но вы не получаете доступ к нему из производного класса. Вы получаете доступ к нему из main().
При использовании класса действительно нет разницы между защищенными и частными членами. Ни один из них не доступен для всего, что использует класс.
class A {
private: int privateNum;
protected: int protectedNum;
public: int publicNum;
void SetNumbers(int num) {
privateNum = num; //valid, private member can be accessed in member function
protectedNum = num; //valid, protected member can be accessed in member function
}
void main() {
A classA;
classA.privateNum = 1; //compile error can't access private member
classA.protectedNum = 1; //compile error can't access protected member
classA.publicNum = 1; //this is OK
classA.SetNumbers(1); //this sets the members not accessible directly
}
Разница вступает в силу, если вы наследуете класс с защищенными членами.
class B : public A {
}
Все частные члены базового класса по-прежнему являются частными и не будут доступны для производного класса. Защищенные члены, с другой стороны, доступны для унаследованного класса, но до сих пор не доступны вне унаследованного класса.
class B : public A {
public:
void SetBNumbers(int num) {
privateNum = num; //compile error, privateNum can only be accessed by members of A, not B
protectedNum = num; //this works, as protected members can be accessed by A and B
}
}
void main() {
B classB;
classB.publicNum = 1; //valid, inherited public is still public
classB.protectedNum = 1; //compile error, can't access protected member
classB.privateNum = 1; //compile error, B doesn't know that privateNum exists
classB.SetBNumbers(1); //this sets the members not accessible directly
}
"Защищенный" означает защиту от доступа вне функции-члена или функцию-член производного класса. "Основная" функция не является членом какого-либо класса, но она пытается напрямую получить доступ к переменной-члену.
Вы точно видите, что ожидаете. Попробуйте это http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/ для получения информации о спецификациях доступа к наследованию.
Да, вы не можете получить доступ к защищенным элементам данных в основной функции. Но вы можете получить доступ к защищенным членам данных в основном, создав функцию в Derived call.