#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 (не знаю, возможно ли это вообще), ответ отрицательный, так что вы, по-видимому, обнаружили ошибку компилятора.