Why How to Access Private Variables in the Copy Constructor

Why can I access private variables in the copy constructor?

IMHO, existing answers do a poor job explaining the "Why" of this - focusing too much on reiterating what behaviour's valid. "access modifiers work on class level, and not on object level." - yes, but why?

The overarching concept here is that it's the programmer(s) designing, writing and maintaining a class who is(are) expected to understand the OO encapsulation desired and empowered to coordinate its implementation. So, if you're writing class X, you're encoding not just how an individual X x object can be used by code with access to it, but also how:

  • derived classes are able to interact with it (through optionally-pure virtual functions and/or protected access), and
  • distinct X objects cooperate to provide intended behaviours while honouring the post-conditions and invariants from your design.

It's not just the copy constructor either - a great many operations can involve two or more instances of your class: if you're comparing, adding/multiplying/dividing, copy-constructing, cloning, assigning etc. then it's often the case that you either simply must have access to private and/or protected data in the other object, or want it to allow a simpler, faster or generally better function implementation.

Specifically, these operations may want to take advantage of priviledged access to do things like:

  • (copy constructors) use a private member of the "rhs" (right hand side) object in an initialiser list, so that a member variable is itself copy-constructed instead of default-constructed (if even legal) then assigned too (again, if legal)
  • share resources - file handles, shared memory segments, shared_ptrs to reference data etc.
  • take ownership of things, e.g. auto_ptr<> "moves" ownership to the object under construction
  • copy private "cache", calibration, or state members needed to construct the new object in an optimally usable state without having to regenerate them from scratch
  • copy/access diagnostic/trace information kept in the object being copied that's not otherwise accessible through public APIs but might be used by some later exception object or logging (e.g. something about the time/circumstances when the "original" non-copy-constructed instance was constructed)
  • perform a more efficient copy of some data: e.g. objects may have e.g. an unordered_map member but publicly only expose begin() and end() iterators - with direct access to size() you could reserve capacity for faster copying; worse still if they only expose at() and insert() and otherwise throw....
  • copy references back to parent/coordination/management objects that might be unknown or write-only for the client code

C++ - Why can a passed object's private variables be accessed directly in the Copy Constructor?

That's because access specifiers are effective per-class, not per-object. So a class method can access private members of any instance of the class.

All members of a class (bodies of member functions, initializers of member objects, and the entire nested class definitions) have access to all the names to which a class can access. A local class within a member function has access to all the names the member function itself can access.

I can access private members in a copy ctor in C#

private is not object level, it is class level, so objects of the same class know about their private aspects, so are allowed to change private things on other object of the same class.

private prevents other types poking around where they shouldn't go.

how it is possible to acess private variables within copy assignment operator?

'private' in C++ means 'private to this class' not 'private to this instance'. Private members can be accessed by any function in the class, including static functions, and also in functions declared as 'friends' of the class.

C++ private members accessible?

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.

Constructor cannot access private members of its own class

By default class access level is private. If you do not add a public: before the Town constructor it will be private.

class Town{
public: // <- add this
Town(int number):number(number){};
...
private:
int number;
};


Related Topics



Leave a reply



Submit