c++ - 为什么我可以从其他对象访问这个私有(private)成员?

标签 c++ member

我目前正在从 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 始终是 ab 之和。但是,在 set 方法内部...

void Sum::set(int x,int y) {
    a = x;
    b = y;
    sum = a + b;
}

这个不变量仅在最后一行恢复。你有责任恢复不变量,使得从外部看来它始终保持不变。

此外,访问限制是为了隐藏实现细节。在 Sum 示例中,用户不知道成员 sum 存在,并且他们不需要知道它。然而,类方法的定义涉及实现细节。处理不同对象的实现细节没有什么区别,因为它们是相同的。

与你的例子有什么关系?

访问限制的目的是让您确保永远不会违反外部不变量并隐藏实现细节。在 Link 方法中,您必须知道自己在做什么。你必须知道 prevsucc 的含义是什么,无论是 this 的成员还是另一个对象。该方法必须确保不违反不变量:调用erase后,调用者仍然具有有效的Link。为此,您需要处理实现细节:有效的 Link 具有 precsucc

结论:无法访问其他对象的私有(private)方法将是一个主要障碍,并且不会真正带来优势(因为无论如何,在方法内部,您已经在处理类的实现细节,并且经常会暂时违反不变量)。

关于c++ - 为什么我可以从其他对象访问这个私有(private)成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61542077/

相关文章:

c++ - ffmpeg编码过程运行时更新参数

c# - 在不存在的结构布局中循环

c++ - 模板化派生类通过CRTP类继承,获取基类成员对象

c++ - 为什么我们不能在声明时初始化类成员?

c++ - p。上缺少成员初始化程序列表的示例。 184《使用C++进行编程的原理和实践》,第二版

c++ - 在新线程中调用 OpenCV 函数 Canny() 会导致段错误

c++ - 引用初始化表格

c++ - 清除具有重叠内容的像素

c++ - 当使用 LOAD_LIBRARY_AS_DATAFILE 调用 LoadLibraryEx 时,具有独占访问权限的 CreateFileW 成功

c++ - 位掩码作为具有默认参数的成员枚举