Может ли частный оператор быть доступным снаружи? - PullRequest
4 голосов
/ 27 мая 2011

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

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

Ответы [ 5 ]

5 голосов
/ 27 мая 2011

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

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

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

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

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

    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, то вы можете иметь доступ к закрытым членам класса, иначе ваш компилятор будет глючить, вам следует подумать об его изменении!

4 голосов
/ 27 мая 2011

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

class bar {
   friend bool operator==( bar const &, bar const & ) {
      return true;
   }
   bar operator+( bar const & ) {
      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 &, bar const & ); // just declare as friend
   //...
};
bool operator==( bar const &, bar const & ) {
   return true;
}

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

2 голосов
/ 27 мая 2011

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

2 голосов
/ 27 мая 2011

Первый ответ: Нет. Если он доступен извне, то какой смысл быть им 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+ должны быть друзьями класса в вашем коде.

1 голос
/ 27 мая 2011

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

...