I have a class CLASS. Classes A and B are derived from CLASS. CLASS, and therefore A and B too, have a field to hold a pointer to an array of pointers to CLASS.
Say I have a member function of A that does some calculations, creating objects of type A throughout. Pointers to these objects are added to the array stored in the object that is calling the function. The function returns void
and takes no arguments. In class B, I want to do the exact same calculations, except create objects of type B instead. I am trying to write a helper function that can be called in both locations, creating objects of type A in one place and of type B in the other.
The constructors of the two classes A and B are identical, because they are both derived classes from the same base class. In the class A version function, if object A(x, y, z)
is created, I would want the class B version to create B(x, y, z)
, the constructor taking the exact same arguments it would have in the class A version. This goes for every object that gets created.
class CLASS {
public:
CLASS** array
int x, y;
CLASS(CLASS** arr, int xcoord, int ycoord);
virtual ~CLASS();
};
class A : public CLASS {
public:
A(CLASS** arr, int xcoord, int ycoord);
void foo();
virtual ~A();
};
class B : public CLASS {
public:
B(CLASS** arr, int xcoord, int ycoord);
void foo();
virtual ~B();
};
//in A.cpp, definition of foo()
void A::foo() {
int a = some value
if (some condition) { array[a + 1] = new A(array, (a + 1), y); }
else if (other condition) { array[a - 1] = new A(array, (a - 1), y); }
//etc.
}
//in B.cpp, definition of foo()
void B::foo() {
int a = some value
if (some condition) { array[a + 1] = new B(array, (a + 1), y); }
else if (other condition) { array[a - 1] = new B(array, (a - 1), y); }
//etc.
}
I am not too familiar with template functions, but as far as I understand them they allow you to change the type of the function arguments and the return, which does not seem to be useful here.
Is this possible to do efficiently? I know I can just copy and paste the code and change it to make B objects and have a switch to run one or the other, or just have one version in A and one in B, but I am trying to avoid using either of these methods.
It seems to me that using virtual functions for this would be good. But if you really want to you can get around it with some CRTP.
If we add a CLASS_IMPL
class that holds the helper function and make it derive from CLASS
.
template <typename T>
class CLASS_IMPL : public CLASS {
CLASS* makeNew (int x, int y) {
CLASS* ptr = new T(array, x, y);
return ptr;
}
}
Downside here is that we need to change A
and B
to use
class A : public CLASS_IMPL<A> {
class B : public CLASS_IMPL<B> {
Then you can go ahead and change B::foo
to use it.
void B::foo() {
int a = some value
if (some condition) { array[a + 1] = makeNew(a + 1, y); }
else if (other condition) { array[a - 1] = makeNew(a - 1, y); }
//etc.
}