C++私有成员可访问吗?

5

我在我们的信号课上有一个使用C++的项目。当我看到我们教练的代码时,我进行了一些调整,然后发现了这个:

ListData::ListData(const ListData& newlist) 
    : Data(), nbNodes(newlist.nbNodes) {}

这是一个“复制构造函数”,正如他所说的,应该大致相当于以下内容:
ListData::ListData(const ListData& newlist){
  Data = "";
  //copy nbNodes of newList to current instance
  nbNodes = newlist.nbNodes;
}

但是让我感到困惑的是,nbNodes是一个私有成员。如果它是私有的,这个构造函数怎么能访问传递的newListnbNodes呢?


你永远是自己最好的朋友:https://dev59.com/yHRC5IYBdhLWcg3wAcXU#437507 - Martin York
6个回答

11

关于私有成员的一个有趣之处是,同一类型的两个对象可以自由地访问彼此的私有成员。您可以将其视为类始终与自身为朋友。由于这是ListData的构造函数,而newlist也是ListData,因此您可以很好地访问它的私有成员。

这是一个例子:

#include <iostream>

class foo
{
  public:
    foo() { }
    foo(std::string secret) : secret(secret) { }
    void steal_secret(const foo& other) { secret = other.secret; }
    std::string get_secret() { return secret; }
  private:
    std::string secret;
};

int main() {
    foo f1("I'm actually a bar");
    foo f2;
    f2.steal_secret(f1);
    std::cout << f2.get_secret() << std::endl;
    return 0;
}
f2 很高兴并且轻松地从 f1 中窃取了 secret,尽管它是私有的。之所以允许这样做,仅仅是因为 private 并不意味着对一个对象私有 - 它意味着对一个类私有。这简化了实现需要在两个同一类的对象的内部进行一些操作的复制构造函数等函数的工作。这条规则来自于private(§11/1)的定义:

类的成员可以是

  • private;即,只能由声明它的类的成员和友元使用其名称。
  • [...]

请注意,它是以类而不是对象为基础定义的。


1
+1,我喜欢那个“与自己为友”的比喻。 - juanchopanza
“同一类型的两个对象可以自由访问彼此的私有成员”这个说法对我来说似乎不正确。 - Baiyan Huang
更好的说法是,一个类的所有对象彼此之间都是朋友。类本身不需要与自己成为朋友。 - user93353
嗯,我想结论本身是正确的,但并不那么直接 - 当你编写代码时,很难看到一个对象正在访问另一个对象的成员,我会说:在类定义中,您可以自由访问相同类型对象的私有成员。 - Baiyan Huang

6

private关键字具有类语义,而不是对象语义。因此,同一类的其他对象可以访问对象的私有成员。


4

nbNodes 是私有的,属于 ListData 类,而不是该类的特定实例。因此,在类的代码内部,您可以看到其他实例的私有数据。

如果不是这样,每个类都必须导出“getter”以获取每个数据成员,以执行复制构造和复制赋值。


2

private可见性的成员只能在同一的成员函数内访问,没有对对象的限制。

如果函数f()是类C的成员函数,则它可以访问任何实例的Cprivate成员,而不仅仅是由隐式的this指针指向的那些实例(当然,这也适用于static函数,它们根本不接收this指针)。


2

复制构造函数就像任何其他方法一样:您可以从该类的方法访问该类的私有成员,因此您可以在复制构造函数中执行相同的操作(否则,您如何将一个实例的状态复制到另一个实例中?)。


2

根据C++标准第11章“成员访问控制”所述:

private表示只有在该类的成员和友元中才能使用其名称。

这意味着私有成员可以被该类的任何成员访问。

这里的ListData::ListData(const ListData& newlist)是ListData的复制构造函数,它是一个成员函数,因此可以访问类ListData的私有成员。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接