这里有更长时间的讨论:Why do objects of the same class have access to each other's private data?
使用具有整数长度的Line对象的简单示例。 operator+
重载函数可以访问其他行的私有长度(参数const Line &line
,也就是添加到this
行的行)。对于非运算符重载函数(printOtherLine
)和友元函数(printFriendLine
)也是如此。再次作为参数传递的Line不是this
object。
为什么会这样?
#include <iostream>
class Line
{
public:
Line()
{
length = 0;
}
Line(int length)
{
this->length = length;
}
Line operator+(const Line &line)
{
Line newLine(this->length + line.length); // I would have thought
// this would be line.getLength()
// instead of line.length
return newLine;
}
int getLength()
{
return length;
}
void printOtherLine(const Line &otherLine){
std::cout << "Other Line: " << otherLine.length << std::endl;
}
void printLine(int lineNumber){
std::cout << "Line " << lineNumber << ": " << this->length << std::endl;
}
friend void printFriendLine(const Line &friendlyLine);
private:
int length;
};
void printFriendLine(const Line &friendlyLine){
std::cout << "Friendly Line: " << friendlyLine.length << std::endl;
}
// This function will not compile
// void printUnassociatedLine(const Line &line){
// std::cout << "Unassociated Line: " << line.length << std::endl;
// }
int main()
{
Line l1(10);
l1.printLine(1);
Line l2(15);
l2.printLine(2);
Line l3 = l1 + l2;
l3.printLine(3);
Line l4(7);
l3.printOtherLine(l4);
printFriendLine(l4);
return 0;
}
Line 1: 10
Line 2: 15
Line 3: 25
Other Line: 7
Friendly Line: 7
答案 0 :(得分:0)
在C ++中,无论使用哪个对象,X类的所有代码都可以访问X的所有部分。
这甚至包括嵌套在X中的类定义中的代码。
关于我所知道的推理理由,后合理化,但访问限制的目的是使一个类更容易正确使用,更难以正确使用,对于其他代码。班级&#39;自己的代码是可信的,无论如何都必须使用所有类。因此限制课程并没有多大意义。以任何方式拥有自己的代码。
关于访问protected
数据成员存在一个有趣的技术问题。类Base
中引入的受保护数据成员可以直接在派生类Derived
中访问,但仅适用于静态已知类型为Derived
的对象或从Derived
派生的类。这可以确保您不会无意中获取访问权限,并使您的代码依赖于其他人的课程&#39;内部,只是来自一个共同的基类。
class Base
{
protected:
int x_ = 666;
};
class Derived
: public Base
{
public:
auto uh_oh( Base const& other ) const
-> int
{ return x_ * other.x_; } //← Nyet!
};
auto main()
-> int
{
Derived a
Derived b;
return a.uh_oh( b );
}
有两种常见的解决方法,其中一种确实需要访问权限。一种是在基类中引入一个访问器函数。另一种是为成员指针使用类型系统漏洞,如下所示:
class Base
{
protected:
int x_ = 666;
};
class Derived
: public Base
{
public:
auto uh_oh( Base const& other ) const
-> int
{ return x_ * other.*&Derived::x_; } // A somewhat dirty trick.
};
auto main()
-> int
{
Derived a;
Derived b;
return a.uh_oh( b );
}
此处还有最佳做法的隐含问题:当您拥有getLength
之类的访问者,并且还可以访问&#34;&#34;成员变量length
,是否应该优先使用其中一个?
嗯,可能是后来人们希望改变实施,例如长度可能以某种方式计算而不是直接存储,如果代码通常使用访问器函数,那么这样做的工作就更少了。但另一方面,使用访问器编写代码可能需要做更多工作,调试此类代码可能需要做更多工作。所以至少就我所知,在每种情况下都是常识,直觉决定。 ; - )