lena242
lena242

Reputation: 55

Why can I access this private member from an other object?

I am currently learning C++ from Stroustrup's Programming: Principles and Practice and there is an example I cannot really understand. There is a class called Link which looks like this.

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;


}

What I do not understand is why prev->succ = succ; is correct since I am assigning to a private member of an object from an other object. What am I missing here?

Upvotes: 3

Views: 101

Answers (4)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123263

Access is per class not per object. Many things would not work as they do if access would be per instance. For example this type

class foo {
    int x;
};

Has a compiler generated copy constructor which is something like this:

foo::foo(const foo& other) {
    x = other.x;
}

Access restictions are for encapsulation and encapsulation is to make sure that the class invariants are not violated. However, typically invarants are violated temporarily inside methods. For example consider this class

class Sum {
    int a = 0;
    int b = 0;
    int sum = 0;
public:
    void set(int x,int y);
    int get_sum() { return sum; }
};

The invariant here is that sum is always the sum of a and b. However, inside the set method...

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

This invariant is only restored on the very last line. It is your responsibility to restore the invariant such that from outside view it always holds.

Further, access restriction is to hide implementation details. In the Sum example, the user has no knowledge that the member sum exists and they need not know about it. However, the definition of the class methods are dealnig with implementation details. Dealing with implementation details of a different object makes no difference, because they are the same.

What is the relation to your example?

The purpose of access restrictions is to allow you to make sure from outside invariants are never violated and to hide implementation details. Inside a method of Link you have to know what you are doing. You have to know what is the meaning of prev and succ, wether its the members of this or another object. The method has to make sure that the invariants are not violated: After calling erase the caller still has a valid Link. And to do that you are dealing with implementation details: a valid Link has prec and a succ.

Conclusion: Not being able to access private methods of other objects would be a major hurdle and not really bring an advantage (because anyhow while inside a method you are already dealing with implementation details of the class and you often do violate invariants temporarily).

Upvotes: 2

Caleth
Caleth

Reputation: 63152

Access restrictions apply to names, not objects.

From [class.access]:

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.

  • protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see [class.protected]).

  • public; that is, its name can be used anywhere without access restriction.

(emphasis added)

Upvotes: 2

con ko
con ko

Reputation: 1416

You can ask yourself a question, how do copy constructors work.

encapsulation is for classes, not objects.

encapsulation is a way to "hide" the code to outside the class. In the class, every private field and function can be accessed. It's not a way to protect the objects, it's a way to hide implementations which users of the class don't need to know the them to improve developing effeciency.

Upvotes: 0

donkopotamus
donkopotamus

Reputation: 23206

Because private members are private to the class, not just the instance.

Thus all instances of Link can see each other’s private members, not just their own.

Upvotes: 0

Related Questions