0

When I call a copy constructor for class B with values ​​(string lan, const B& kop) in the initialization list of this constructor, I use B(kop) which is an undefined copy constructor.

As I understand it, the compiler then creates such a constructor itself, and miraculously it manages to copy the lan and licz fields of the base class and, of course, its own tf field.

However, in my opinion, it should not be possible because these two fields are private in the base class and public setters are needed in the base class, e.g. for licz I have not defined one. Does the compiler create such a setter itself?

Nevertheless, the program executes correctly.

Please explain how this happens from a technical perspective, and how the compiler deals with it.

abc.h:

#ifndef ABC_H_INCLUDED #define ABC_H_INCLUDED #include <iostream> #include <string> #include <iomanip> using namespace std; class A { private: string lan; int licz; public: A(string lan, int licz) : lan(lan), licz(licz) {} virtual void drukuj() const { cout<<lan<<" ; "<<licz<<endl; } string getLen() const { return lan; } int getLicz() const { return licz; } void setString(string lan) { this->lan=lan; } }; class B : public A { private: bool tf; public: B(string lan, int licz, bool tf) : A(lan,licz), tf(tf){} B(string lan, const B& kop) : B(kop) { A::setString(lan); } void drukuj() const override { cout<<boolalpha<<A::getLen()<<" ; "<<A::getLicz()<<" ; "<<tf<<endl; } }; #endif // ABC_H_INCLUDED 

main.cpp:

#include "abc.h" int main() { A a("obiekt klasy A",1); B b("obiekt klasy B", 2, true); B c("kopia obiektu b", b); a.drukuj();//drukuje wszystkie składowe obiektu a b.drukuj(); c.drukuj(); return 0; } 
2

2 Answers 2

2

However, in my opinion it should not be possible because these two fields are private in the base class and public setters are needed in the base class ...

If such copying would not work then inheritance would be of rather limited use. Public setters is not actually object orientation, but thats a discussion for elsewhere.

For illustration consider this example:

#include <iostream> struct A { A() = default; A(const A&) { std::cout << "hello\n"; } }; struct B : A { B() = default; }; int main() { B b; B c(b); } 

B has a compiler generated copy constructor. This copy constructor uses As copy constructor to copy the A subobject, hence the output is:

hello 

Live Demo

In your example also A copy constructor is compiler generated.


Also note that private does not imply restrictions for the compiler. private does not mean that it is totally impossible to access the member. There exist tricks to access them if you want also from outside the class. The point of private is to prevent accidential access by the programmer.

Sign up to request clarification or add additional context in comments.

Comments

1

The copy constructor of B can't possibly construct members of A directly, it has to call some constructor of A. In this case it calls the copy constructor of A, which is generated implicitly.

I have not defined [a setter], does the compiler create such a setter itself? [to access the private members]

You (or a compiler, rather) don't need a setter to access a private member. All you need is to know its offset in the enclosing class, which the compiler obviously knows.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.