Почему я не могу получить доступ к защищенному члену из экземпляра производного класса?

Я не делал С++ через некоторое время и не могу понять, почему следующее не работает:

class A {
protected:
  int num;
};

class B : public A {
};

main () {
  B * bclass = new B ();
  bclass->num = 1;
}

Компиляция:

ошибка C2248: "A:: num": не может получить доступ к защищенному члену, объявленному в классе "A"

Не должны ли защищенные члены быть доступными по производным классам?

Что мне не хватает?

Ответ 1

да защищенные члены доступны производными классами, но вы обращаетесь к нему в функции main(), которая находится за пределами иерархии. Если вы объявите метод в классе B и получите доступ к нему, это будет нормально.

Ответ 2

Да, защищенные члены доступны производному классу, но только изнутри класса.

Пример:

#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.

Ответ 3

Он доступен в рамках функций B, но вы пытаетесь получить к нему доступ в основном.

Ответ 4

Но вы не получаете доступ к нему из производного класса. Вы получаете доступ к нему из main().

Ответ 5

При использовании класса действительно нет разницы между защищенными и частными членами. Ни один из них не доступен для всего, что использует класс.

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
}

Ответ 6

"Защищенный" означает защиту от доступа вне функции-члена или функцию-член производного класса. "Основная" функция не является членом какого-либо класса, но она пытается напрямую получить доступ к переменной-члену.

Ответ 8

Да, вы не можете получить доступ к защищенным элементам данных в основной функции. Но вы можете получить доступ к защищенным членам данных в основном, создав функцию в Derived call.