#include <iostream>
usingnamespace std;
class base {
public:
base(int x) : a(x) {}
base(const base& b) {cout << "copy constructor called" << endl; a = -1;}
int a;
};
base makeBase(const base& B) {
base madeB(5);
return madeB;
}
class derived : public base {
public:
derived(const base& B, int y) : base(makeBase(B)), c(y) {}
int c;
};
int main()
{
base base1(2);
derived derived1(base1,3);
cout << "derived1.a = " << derived1.a << endl;
}
I think OP is asking about why base( makeBase( B ) ) does not call base::base( const base& ) since makeBase returns a base, and the answer is because of return value optimization. makeBase's local variable madeB is actually constructed in place at the right location in memory, hence no temporary and copy is needed.
Thanks for the reply... it confirms what I kind of thought. Is there a way to force to call the copy constructor. The problem is if you have a member that is a pointer, you need to pass trough the copy constructor to make sure it is handle properly.
I should maybe have post that code first since it is the problem I actually have.
derived2.ptr.ptrToBase doesn't point at the right place. Normally, my copy constructor would take care that it points at the right place.
The problem in your most recent example is related to something else, and would not be solved by removing the optimization:
line 27 you have a base object Base which is local to makeFirstDerived. Once makeFirstDerived exits, Base is destroyed.
You are supplying a pointer to Base to your madeFirstDerived, which records that pointer internally.
Since Base dies at the end of the function, the pointer becomes bad and points to garbage as soon as the function exits. This is why line 46 is spouting out garbage. The object ptrToBase points to no longer exists.
I am dealing with a base class that all the data are private such that nothing can be changed after creation. I want to take an instance of that base class, to create a derived class, but I want to change some of the data of that base class.
I am dealing with a base class that all the data are private such that nothing can be changed after creation.
There isn't anything extraordinary about that. Attributes should be private. Personally, I don't see any valid purpose in the base_ptr class. In your example, it appears that the base classes only attribute is public. It can easily be changed directly by any other class (which is wrong by the way).
Well, why don't you just provide proper interfaces for all of your classes? The derived class can easily call the public / protected functions of the base class so I am unclear on why your derived classes need to have attributes pointing to the same base class that they already have access to.
Sorry, I probably wasn't clear. The base class is "read only", no setters, only getters. There is a good reason to design it that way, which I don't think is relevant here. In that example, I simply wanted to make a point about my problem... I didn't bother putting things private and so on.
The reason for the pointer is a memory issue. Imagine that you have many reconstructed objects that are made of some basics objects. We put all the basic objects in a class and then the reconstructed objects of the class only point to the basics objects they are made of. A basic object can be used by many reconstructed object.
That doesn't make sense. A class of type derived will always construct a base class. You cannot prevent that. Of course there is good reason to design classes properly with private attributes but that isn't what you showed in the examples and I don't see how that issue is relevant to what you are doing with the copy constructor. Furthermore you specifically stated,
but I want to change some of the data of that base class
. So is the base class read-only or not? If you say that there is good reason for it to be read-only why are you also saying that you need to change the base classes value?
Ok, I tried to come up with an analogies that describe the situation.
You have a painting. The painting is simply colors with their positions on the paper. You have objects in the painting, clouds, sun, etc. Those aren't physical, just definition of colors with position in the painting. So a cloud simply points the colors and positions it is associated with on the painting. Once I am done painting, I naturally forbid anybody to touch it!
Now let say that I have access to new colors in addition to the previous ones. I want to repaint the same painting, but "better" with the new colors (of course, my derived class). Sometime I'll use the same thing (same colors at the same position), but sometime I'll use the new colors. Again, once this is done, it is forbidden to touch the painting.
Later I want to look at both painting and say: hey, look at the clouds... which ones do you prefer?
I guess I could have gone for that... but I found another solution that keeps the same design. All needed to be changed is (in the second example I posted):
firstDerived(const base& b) : base(b), ptr(b) {}
for
firstDerived(const base& b) : base(b), ptr(*this) {}