I have a C++ slicing problem. I'm new to C++, so maybe just too dumb to realize this can't be done.... I have tried a variety of workarounds, and my current best approach looks like below. (I need to do something like this to avoid changing a ton of interfaces in a very large legacy code base. Not claiming this is elegant style in any way!!)
Having troubles making this compile. Is the idea sound? Or is the entire approach doomed to failure? The constructors for references appear to be the issue. I've read Stroustrup's "C++ Programming Lanugage" (or at least what I thought were the relevant sections) but it didn't help.
class FOO {};
class FOOSUBCLASS : public FOO {
public:
FOOSUBCLASS(const int id = 0) : _id(id) {}
private:
int _id;
};
class BAR {
public:
BAR(const FOO foo) : _foo(foo), _realFoo(&_foo) { }
BAR(const FOOSUBCLASS foosc) : _foosc(foosc), _realFoo(&_foosc) {}
private:
FOO _foo;
FOOSUBCLASS _foosc;
FOO& _realFoo;
};
The compiler doesn't like my _realFoo(&_foo)
line. I'd like the reference to _foo
, to just be the reference from the member variable in the class. Is that not possible in C++?
Here's the specific error from VS2005:
'initializing' : cannot convert from 'FOO *' to 'FOO &'
_foo
is aFOO&
.&_foo
is aFOO*
.The compiler
cannot convert from 'FOO *' to 'FOO &'
.what you want is
..., _realFoo(_foo)
Unrelated: What you probably actually want is a
std::unique_ptr<FOO>
member instead. This will be much smaller, and much less error prone.The struct as you have it now, contains a full and complete instance of
FOO
, and a full and complete instance ofFOOSUBCLASS
, and a reference. At least put the twoFOO
thingies in a union, so the size ofBAR
is only slightly bigger than the biggestFOO
derivative. That would probably use the same memory as aunique_ptr<FOO>
. Unfortunately,union
s are a common source of bugs in C and C++.Another problem is if someone comes along and writes
Then you'll have to go and find the
BAR
class and change it and make it even bigger, and recompile all of your code that usesBAR
everywhere. Whereas, if you used aunique_ptr<FOO>
, then you won't have to changeBAR
or recompile anything. So smaller chance of error.