C ++ Доступ к классу друзей-> member-> public метод? - PullRequest
1 голос
/ 20 августа 2010

Является ли следующий код допустимым в C ++.Доступ к общедоступному методу члена класса?Я знаю, это звучит запутанно, и лучший способ показать это в коде.Мне было интересно, если TestClassC :: Method () допустим в приведенном ниже коде?

Я скомпилировал (g ++), и он работает, однако я сталкиваюсь с ситуацией, когда он вызывает ошибку сегментации надругая машина / дистрибутивы в TestClassC :: Method ().Что заставляет меня задуматься, если это-> classA_Ptr-> classB.Method ();законно в C ++.

#include <iostream>

using namespace std;

class TestClassB
{
   public:
      TestClassB(void){};
      ~TestClassB(void){};
      void Method(void){
         cout << "Hello Again" << endl;
      }
};


class TestClassC; //Forward Declaration
class TestClassA
{
   friend class TestClassC;

   public:
      TestClassA(void){};
      ~TestClassA(void){};

   private:
      TestClassB  classB;
};


class TestClassC
{
   public:
      TestClassC(TestClassA* a_Ptr){
         this->classA_Ptr = a_Ptr;
      }
      ~TestClassC(void){};

      void Method(void){
         //Is this Valid/Legal ???
         this->classA_Ptr->classB.Method();
      }

   private:
      TestClassA*  classA_Ptr;
};



int main()
{
    cout << "Hello world!" << endl;

    TestClassA testClassA;
    TestClassC classC(&testClassA);

    classC.Method();

    return 0;
}

Ответы [ 3 ]

4 голосов
/ 20 августа 2010

Модификаторы доступа public / private / protected применяются во время компиляции, а не во время выполнения.SEGFAULT - это ошибка времени выполнения, а не ошибка времени компиляции.Таким образом, в будущем, если вы получите SEGFAULT, вы можете быть уверены, что он не связан с уровнем доступа.Похоже, ваша путаница основана на том, применяются ли модификаторы доступа напрямую, косвенно, транзитивно и т. Д. Модификаторы доступа работают самым простым и понятным способом: они применяются только напрямую, к функциям или переменным, которые были объявленыв этом классе и контролировать доступ через данный класс к этим элементам.Если у вас есть доступ к такому элементу, дальнейший доступ определяется исключительно его собственными модификаторами доступа.

SEGFAULT обычно указывает на недопустимый доступ к памяти.Если вы испытываете SEGFAULTS, посмотрите, где вы разыменовываете указатели (когда у вас есть * X или X-> Y).Распространенные причины SEGFAULTS включают разыменование NULL, автономный доступ к массиву и использование объекта через указатель, когда рассматриваемый объект уже удален путем выхода из области видимости.

2 голосов
/ 20 августа 2010

Да. Спецификация друга предоставляет TestClassC доступ к любым защищенным или закрытым членам TestClassA. Это означает, что он получает доступ к члену classB. После этого к правилу TestClassC можно применить обычные правила. И поскольку Method () является общедоступным, TestClassC разрешается вызывать его, как если бы он получил экземпляр TestClassB любым другим способом.


Относительно ошибки сегмента:

Публичный / защищенный / личный / друг - все это ограничения времени компиляции. Они не должны влиять на работу кода во время выполнения.

Этот точный код вызывает ошибки? Или это просто нечто похожее по концепции? Если это не тот же самый код, то вы убедились, что все указатели действительно допустимы в проблемном коде?

1 голос
/ 20 августа 2010

Вызов открытых методов любого класса является действительным / законным, если класс однозначно доступен, и у нас есть допустимое выражение объекта для доступа к нему. Фактически именно поэтому это было обнародовано во-первых. Ваш код выглядит хорошо для меня.

...