5

I have this project in our signals class which uses C++. I was tinkering with our instructors code when I saw this:

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

This is a "copy constructor" as he says, and should be roughly equivalent to the following:

ListData::ListData(const ListData& newlist){
  Data = "";
  //copy nbNodes of newList to current instance
  nbNodes = newlist.nbNodes;
}

But what bothers me is that nbNodes is a private member. How could this constructor access the nbNodes of the passed newList if it's private?

Joseph
  • 117,725
  • 30
  • 181
  • 234

6 Answers6

11

An interesting thing about private members is that two objects of the same type can access each others private members freely. You can think of it as a class is always friends with itself. Since this is the constructor for ListData and newlist is also a ListData, you can access its privates just fine.

Here's an example of this:

#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 happily and easily steals the secret from f1, despite it being private.

The reason for this being allowed is simply because private doesn't mean private to an object - it means private to a class. This eases the implementation of functions such as copy constructors that require doing some work to the internals of two objects of the same class.

The rule comes from the definition of private (§11/1):

A member of a class can be

  • private; that is, its name can be used only by members and friends of the class in which it is declared.
  • [...]

Note that it is defined in terms of classes and not objects.

Community
  • 1
  • 1
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • 1
    +1, I like that "friend with itself" analogy. – juanchopanza Feb 27 '13 at 14:31
  • >>`two objects of the same type can access each others private members freely` This statement seems not correct to me. – Baiyan Huang Feb 27 '13 at 14:43
  • Better way to put it is all objects of a class are friends of each other. Class doesn't need to be friends with itself. – user93353 Feb 27 '13 at 14:43
  • well, I guess the conclusion itself is right, but just not that straightforward - when you write code, it is hard to see an object is accessing another object's member, I would say: In a class definition, you are free to access private member of an object of the same type. – Baiyan Huang Feb 28 '13 at 01:46
6

The private keyword has class semantics not object semantics. So private members of an object of a class are accessible to other objects of the same class.

user93353
  • 13,733
  • 8
  • 60
  • 122
4

nbNodes is private to the ListData class, not to a particular instance of that class. So, inside the code of the class, you can see the private data of other instances of that class.

If it weren't so, every class would have to export "getters" for every single data member in order to perform copy construction and copy assignment.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
2

Members with private visibility are members that can only be accessed within member functions of the same class they are members of, without restrictions on objects.

If function f() is a member function of class C, it can access the private members of any instance of C, not just those pointed by the implicit this pointer (which, of course, makes this valid for static functions as well, which do not receive a this pointer at all).

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
2

A copy constructor is just like any other method: as you can access private members of a class from a method of that class, you can do the same with your copy constructor (else, how could you copy the state of an instance to the class to another one?).

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
2

From C++ Standard, Chapter 11: Member Access Control:

private; that is, its name can be used only by members and friends of the class in which it is declared.

That means a private member could be accessed by any members of that class

Here ListData::ListData(const ListData& newlist) is a copy constructor of ListData, which is a member function thus could access class ListData's private member.

Baiyan Huang
  • 6,463
  • 8
  • 45
  • 72