I've always worked with pointers and avoided references because I didn't understand how to work with them very well. Today I was working on a small project and decided to use references instead and ran into some behavior I'm not sure how to work around. Basically I have a factory (Factory) that creates either an object of type B or C, both of which are derived from A.
class Factory
{
public:
void create(A& container, int a) //This is for creating an object of B
{
B result;
result.Func(a);
container = result;
}
void create(A& container, int a, int b) //This is for creating an object of C
{
C result;
result.Func(a, b);
container = result;
}
}
class A
{
public:
virtual void Func(int a) //This is used for an object of B
{
var1 = a;
};
virtual void Func(int, int) {}; // This is used for an object of C
private:
int var1;
}
class B : public A
{
//Relies of base class Func to set the variable var1;
}
class C : public A
{
public:
void Func(int a, int b)
{
A::Func(int a)
var2 = a1;
}
private:
int var2;
}
The issue arises when I try to do the following
Factory factory;
A a;
factory.create(a, 1); //Works fine because B and A have only 1 variable
factory.create(a, 1, 1); //a only contains A part of C
When I check the debugger, there is no sign of var2 to in a after the 2nd create call. I understand its because I'm using a reference to the base type of C and only the A part of C gets stored in the container, but is there a workaround? I know I can just switch A to A*, but I'm interested if there is a non-pointer based solution.
TL;DR Is there a way to store an object of a derived class in a reference of the base class without using pointers?
I feel compelled to point out that a reference of type T is logically equivalent to a T * const. So technically, you can't get around using pointers.
To answer your question, it is absolutely possible to store a derived class in a reference to a base class. The issue is that A, B, and C all have potentially difference sizes. Here is one solution:
#include <stdio.h>
class A
{
public:
virtual void Function()
{
printf("A\n");
}
};
class B : public A
{
public:
virtual void Function()
{
printf("B: %d\n", var1);
}
int var1;
};
class C : public A
{
public:
virtual void Function()
{
printf("C: %d, %d\n", var1, var2);
}
int var1, var2;
};
class Factory
{
public:
A & Create(int a)
{
B &b = *new B;
b.var1 = a;
return b;
}
A & Create(int a, int b)
{
C &c = *new C;
c.var1 = a;
c.var2 = b;
return c;
}
};
Called like:
Factory factory;
A &a1 = factory.Create(0);
A &a2 = factory.Create(1, 2);
a1.Function();
a2.Function();
Which will print: B: 0 C: 1, 2
Unfortunately, it's not possible to allocate an A and then assign a B or C to it later, since their sizes don't match. You either must use a reference/pointer with dynamic allocation, or know the type ahead of time.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.