#include <iostream>
class Bar
{
protected:
public:
int & x;
Bar(int & new_x)
:x(new_x)
{}
Bar & operator = (const Bar toCopy)
{
x = toCopy.x;
return *this;
}
};
int main()
{
int x1(1);
int x2(2);
Bar bar = Bar(x1);
std::cout << bar.x << std::endl;
bar = Bar(x2);
std::cout << bar.x << std::endl;
bar.x = 5;
std::cout << bar.x << std::endl;
std::cout << x1 << std::endl;
std::cout << x2 << std::endl;
}
The output is:
1
2
5
5
2
What I am trying to do is copy x and save it within the object bar.
The output suggests to me that the assignment operator has not done its magic, both in terms of copying and taking the value of the new object. I have followed this link.
Changing x into a value rather than a reference is not possible, as in the real program x is an abstract class.
Please if possible abstain from using heap assignment.
EDIT:
1. I realized that I have just butchered the C++ language. I would like to apologize to all “C++ian” speaking computers. My motivation was to assign a member abstract variable on the stack. As far as I understand, it cannot be done on the stack, because the size of the derived class is not known at compile time.
2. OK… I am a total n00b…(no sh*t, Sherlock!). “Effective C++ programming” @rhalbersma is a must have. It contains essentials, yet you wont find them anywhere (copy constructions, copy initializer),.. in one place anyway.
References can be confusing. So can
constpointers. I’ll try to clear things up by talking about both of them at the same time. What can I say, I’m an optimist.First,
constpointers.We’ll start with a class called
Foo. We can have a pointer to this class — aFoo*. We can have a pointer to aconstinstance of this class — aFoo const*. And we can have aconstpointer to a non-constinstance of this class — aFoo*const.A
Foo const*is a pointer you can change to data you cannot change.A
Foo*constis a pointer you cannot change to data you can change.I’ll assume you got that. I am, after all, an optimist. Next, lets look at references.
While it is true that references are aliases, sometimes it helps to think about them in a world where things have concrete implementations in terms of other types.
A
Foo&is analogous to aFoo*const— a non-changeable “pointer” to an instance ofFooyou can change. So theFooyou are talking about is always the same one, but you can change its state.Now, it is a bit more than that. There is some syntactic sugar. When you create a reference to another variable, it does the
&automatically — so when you do aFoo& f = a;, this is analogous toFoo*const f = &a;.Second, when you use
., it does the same as->in the pointer case. (And similarly for (most?) other operators)Third, when you do assignment, it clearly cannot change the pointer’s value — because it is
const— but instead it changes the value of the thing pointed to. SoFoo& f = a; a = b;does the equivalent ofFoo*const f = &a; *f = b;.It assigns the thing pointed to, rather than the pointer, when you use
operator=. But when you initialize it, it doesn’t useoperator=, even if you have a=token.Initialization is not the same as assignment in general, and the semantics of what happens with a
&reference and a*pointer in initialization and assignment are very different.Foo& f = a; f = b;does two completely different things. Initialization of a reference initializes the “constpointer” portion — assignment to a reference modifies the thing pointed to.My personal name for how initialization and assignment mean different things with references is “reference semantics”, as opposed to “pointer semantics” where both initialization and assignment change what thing is being pointed to. In “reference semantics”, initialization picks what thing is being pointed to, and assignment changes the state of the thing that is pointed to.
This is highly confusing, and I hope I helped make it confusing in a different way.