Почему я не могу получить доступ к защищенному члену из экземпляра производного класса? - PullRequest
12 голосов
/ 09 июня 2009

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

class A {
protected:
  int num;
};

class B : public A {
};

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

Компиляция приводит к:

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

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

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

Ответы [ 8 ]

32 голосов
/ 09 июня 2009

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

13 голосов
/ 09 июня 2009

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

пример:

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

8 голосов
/ 09 июня 2009

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

6 голосов
/ 09 июня 2009

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

4 голосов
/ 09 июня 2009

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

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
}
3 голосов
/ 09 июня 2009

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

1 голос
/ 09 июня 2009

Вы видите именно то, что ожидали. Попробуйте это - http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/ для получения информации о спецификаторах доступа к наследованию.

0 голосов
/ 10 октября 2014

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...