For a class hierarchy like:
struct base { int i = 1; };
struct derived final : public base
{
int j = 2;
void f() { i = 2; }
};
// more derivations from base
I'd like a way to create an instance of derived
but using an existing base
instance. For example:
base b; // b.i == 1
{
derived d;
d.f(); // d.i == 2
}
Is there a way to set things up so that after calling d.f()
the value of b.i
is 2? As I've tried to indicate, the lifetime of derived
is fairly short.
Conceptually, I want to make base
look like derived
for a little while, with "look like" meaning access to d.j
. When I'm done, I want the changes made to d.i
to "stick to" b.i
. The obvious solution of base& b
member variable doesn't work because accessing i
requires different syntax: b.i
instead of i
.
Copying the derived
instance back to base
when I'm done would work; but that seems rather smelly.
{
derived d;
d.f(); // d.i == 2
b = d; // copy, YUCK!
}
But I really only want and need one instance of base
.
What's actually going on is that I'm trying to simulate nested functions; but I don't want to change the syntax to access either i
or j
.
In pseudo-code, I want to do something like:
struct s final
{
int i = 1;
void f()
{
int j = 2;
auto g = [&]();
}
// ... other code ...
void f::g() { i = 10; j = 20; }
};
In other words, the actual code for the "local function" is away from where it's declared.
I don't see any way to share the same member variable of object
b
with a different objectd
that serves as a decorator/view ofb
, because different objects have different sets of values for member variables.If
derived
is derived frombase
, then thebase
-object is part of everyderived
-object and you cannot destroy thederived
-object without destroying the intrinsicbase
-object as well.If
derived
is not derived frombase
, then you cannot replace variables that expect abase
-object with an object of typederived
in your code; anyxxx.i
in your code will either work forxxx
being an object of typebase
or forxxx
being an object of typederived
, but not for both. So applying a common code containingxxx.i
to objects ofderived
and objects ofbase
will not work (unless you have a macro like#define impl_f(b) { (b).i = 2; }
, but I don't thing that you think of reusable code in form of makros).A way I could think of is a derived class that enforces to be initialized with a
base
-object and copies back the (changed) values to this base-object oncederived
is destroyed: