-3

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.

J. Cal
  • 157
  • 1
  • 3
  • 18
  • Post some code. –  Feb 25 '18 at 03:09
  • @NeilButterworth Ok, code coming soon. – J. Cal Feb 25 '18 at 03:10
  • @NeilButterworth https://pastebin.com/mYQf4Jn7 – J. Cal Feb 25 '18 at 03:25
  • 1
    Post a [MCVE] in text, copied directly into the question, here on StackOverflow. Use the `{}` button to format it. No links to code on other sites are allowed. What is a "helper function"? That is not standard C++Speak. – Jive Dadson Feb 25 '18 at 03:30
  • @JiveDadson Code is there now. I don't have a MCV example because there is no bug or anything to verify -- I am just asking a question about the abilities of C++ and if it is possible to do what I am aiming to do. I am new to the language so apologies if my vocabulary is wrong. Here I mean helper function in the sense that it is a function that eliminates redundancy -- and A and B version are exactly the same except for the types of objects being created. The "helper function" would take an argument, and depending on that either make objects of class A or of class B. – J. Cal Feb 25 '18 at 03:48

1 Answers1

0

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.
}
super
  • 12,335
  • 2
  • 19
  • 29