Может ли частный оператор быть доступен извне?

#c #class #private

#c #класс #Частное

Вопрос:

т.е. если я определяю операторы == и в моем классе в закрытом разделе, могут ли они быть доступны из main?

Это работает в MSVS 2008 и 2010, но мне кажется, что это ошибка в компиляторе. Так ли это?

Комментарии:

1. Когда я начинал программировать на C , я пару раз приходил к своему наставнику и говорил: смотрите, в компиляторе ошибка! мой код не компилируется / ведет себя так, как должен . Он обычно улыбался в ответ и отвечал: Скорее всего, ошибка находится между креслом и клавиатурой . У компиляторов есть ошибки, но чаще всего ошибочным является наш код или наше понимание этого кода. Вы должны опубликовать фактический код.

2. @David: Забавно, «предложение», которое я получил, исходит от SE и звучит так: «Как вы определяете, плохой ли совет от старшего разработчика?» … Ах!

Ответ №1:

Функции или члены, объявленные в спецификаторе частного доступа, не будут доступны за пределами функций-членов класса.

В C существует 3 спецификатора доступа для класса / структуры / объединения. Эти спецификаторы доступа определяют, как можно получить доступ к членам класса. Конечно, любой член класса доступен внутри этого класса (внутри любой функции-члена того же класса). Переходя к спецификаторам типа доступа, они:

Public — Члены, объявленные как общедоступные, доступны извне класса через объект класса.
Защищенный — Члены, объявленные как защищенные, доступны извне класса, НО только в производном от него классе.
Private — Эти члены доступны только изнутри класса. Доступ извне запрещен.

Друзья, спешим на помощь!
Объявление функции как дружественной внутри другого класса позволяет этой функции получать доступ ко всем функциям-членам внутри класса независимо от правил спецификатора доступа. друг Это способ обойти правила спецификатора доступа, изложенные в C . Аналогично, класс, объявленный как friend внутри другого класса, позволит классу, объявленному как friend, иметь доступ ко всем членам класса. Обратите внимание, что объявление friend может быть задано под любым параметром access, и это будет иметь тот же эффект.

Пример исходного кода:

     class MyClass
    {
        public:
            int a;
        protected:
            int b;
        private:
            int c;
            friend void doSomething(MyClass obj);
    };

    void doSomething(MyClass obj)
    {
        obj.a = 10;     //Allowed
        obj.b = 20;     //Allowed, 
        obj.c = 30;     //Allowed, 
    }


    int main()
    {
        MyClass obj;
        obj.a = 10;     //Allowed
        obj.b = 20;     //Not Allowed, gives compiler error
        obj.c = 30;     //Not Allowed, gives compiler error
    }
  

Итак, в вашем использовании, если вы используете friend , у вас может быть доступ к закрытым членам класса, иначе ваш компилятор глючит, вам следует рассмотреть возможность его изменения!

Комментарии:

1. Поскольку оба VS2008 и VS2010 содержат ошибки в таком распространенном фрагменте кода, я так не думаю. Это не скрытый угловой случай, который, возможно, избежал обнаружения за все время существования VS2008 🙂

Ответ №2:

Вам придется показать код, чтобы получить разумное объяснение, почему компилятор его принимает. Я предполагаю, что вы реализуете их как friend свободные функции. В любом случае, ради аргументации предположим, что у вас есть:

 class bar {
   friend bool operator==( bar const amp;, bar const amp; ) {
      return true;
   }
   bar operator ( bar const amp; ) {
      return *this;
   }
};

int main() {
   bar a, b;
   a == b;    // ok
   //a   b;   // nok: operator  is private from this context
}
  

А теперь объяснение. В примере operator объявлен как функция-член внутри частного раздела, поэтому применяются спецификаторы доступа, и если main он не является другом класса, у него не будет доступа к нему. С другой стороны, operator== реализован как свободная функция (даже если определение предоставляется внутри фигурных скобок класса), и спецификаторы доступа там не применяются.

Код почти эквивалентен (есть небольшая разница, когда дело доходит до поиска) для:

 class bar {
   friend bool operator==( bar const amp;, bar const amp; ); // just declare as friend
   //...
};
bool operator==( bar const amp;, bar const amp; ) {
   return true;
}
  

Где гораздо проще рассуждать о доступности operator== из основной функции.

Комментарии:

1. Да, я не заметил объявления друга : (

Ответ №3:

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

Ответ №4:

Первый ответ: Нет. Если он доступен извне, то какой смысл быть им private ?

Однако есть один нюанс.

Если вы main() подружитесь с классом, то он будет доступен только из main() . Итак, второй ответ: на самом деле это зависит: только функции-члены и друзья могут получить доступ к private члену класса.

 class A
{
  int data; //private 
  friend int main();  //make main() friend of A
};

int main()
{
    A a;
    a.data = 100; //okay - main() is a friend of class A
}
void f()
{
    A a;
    a.data = 100; //error - f() is not a friend of class A
}
  

Это означает, я делаю вывод, что operator== и operator должны быть друзьями класса в вашем коде.

Ответ №5:

Если вы не добавили объявление friend для main (не знаю, возможно ли это вообще), ответ отрицательный, так что вы, по-видимому, обнаружили ошибку компилятора.