我目前正在从 Stroustrup 的《编程:原理与实践》中学习 C++,其中有一个我无法真正理解的示例。有一个名为 Link 的类,如下所示。
class Link{
public:
Link(Link* p=nullptr, Link* n=nullptr, const std::string& label);
Link* erase();
private:
std::string label;
Link* succ;
Link* prev;
};
Link* Link::erase() {
if (this == nullptr) return nullptr;
if(prev) prev->succ = succ;
if(succ) succ->prev = prev;
return succ;
}
我不明白的是为什么
prev->succ = succ;
是正确的,因为我从另一个对象分配给一个对象的私有(private)成员。我在这里缺少什么?
最佳答案
访问是按类而不是按对象进行的。如果访问是按实例进行的,许多事情就不会像现在这样工作。例如这种类型
class foo {
int x;
};
有一个编译器生成的复制构造函数,如下所示:
foo::foo(const foo& other) {
x = other.x;
}
访问限制是为了封装,封装是为了确保不违反类不变量。然而,通常在方法内部会暂时违反不变量。例如考虑这个类
class Sum {
int a = 0;
int b = 0;
int sum = 0;
public:
void set(int x,int y);
int get_sum() { return sum; }
};
这里的不变量是 sum
始终是 a
和 b
之和。但是,在 set
方法内部...
void Sum::set(int x,int y) {
a = x;
b = y;
sum = a + b;
}
这个不变量仅在最后一行恢复。你有责任恢复不变量,使得从外部看来它始终保持不变。
此外,访问限制是为了隐藏实现细节。在 Sum
示例中,用户不知道成员 sum
存在,并且他们不需要知道它。然而,类方法的定义涉及实现细节。处理不同对象的实现细节没有什么区别,因为它们是相同的。
与你的例子有什么关系?
访问限制的目的是让您确保永远不会违反外部不变量并隐藏实现细节。在 Link
方法中,您必须知道自己在做什么。你必须知道 prev
和 succ
的含义是什么,无论是 this
的成员还是另一个对象。该方法必须确保不违反不变量:调用erase
后,调用者仍然具有有效的Link
。为此,您需要处理实现细节:有效的 Link
具有 prec
和 succ
。
结论:无法访问其他对象的私有(private)方法将是一个主要障碍,并且不会真正带来优势(因为无论如何,在方法内部,您已经在处理类的实现细节,并且经常会暂时违反不变量)。
关于c++ - 为什么我可以从其他对象访问这个私有(private)成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61542077/