即。如果我在私有部分的类中定义运算符==和+,它们是否可以从main访问?
它适用于MSVS 2008和2010但对我来说似乎是编译器中的一个错误。是这样吗?
答案 0 :(得分:5)
在类成员函数之外,无法访问在私有访问说明符下声明的函数或成员。
C ++中的类/结构/联合有3个访问说明符。这些访问说明符定义了如何访问类的成员。当然,类的任何成员都可以在该类中访问(在同一个类的任何成员函数内)。继续前进到访问说明符的类型,它们是:
公开 - 声明为Public的成员可以通过类的对象从Class外部访问。
受保护的 - 声明为受保护的成员只能从类BUT外部访问,但只能在从它派生的类中访问。
私有 - 只能在班级内访问这些成员。不允许外部访问。
朋友们来救援!
在另一个类中声明一个函数为 friend ,允许该函数访问类中的所有成员函数,而不管访问说明符规则如何。 朋友 这是一种绕过C ++中规定的访问说明符规则的方法。类似地,在另一个类中声明为朋友的类将允许被声明为朋友的类可以访问该类的所有成员。请注意,可以在任何访问指定符下给出friend声明,它将具有相同的效果。
源代码示例:
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 :(得分:4)
您必须显示代码才能明确解释编译器接受它的原因。我的猜测是你将它们作为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 :(得分:2)
第一个答案是:否。如果它可以从外部访问那么它是什么意思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+
必须是您代码中该类的朋友。
答案 3 :(得分:2)
是的,这是一个错误。它们只能由朋友功能和朋友类访问。所有其他人都不应该访问私人部分。
答案 4 :(得分:1)
如果你还没有为main添加朋友声明(不知道是否可能),答案是否定的,所以你显然发现了一个编译器错误。