jeudi 2 janvier 2020

how to pass subclass as parameter for function expecting base class then pass that object into vector of pointers to those abstract class objects?

TL;DR

I am trying to pass a subclass into a function that expects the subclass's base class and then store a unique pointer of that base class in a vector in a third, completely separate class.

(C++ 11 and higher)

End TL;DR

I have 3 classes total and then my int main().

The base (abstract) class has a constructor and a virtual function. The base class constructor is implemented, the virtual function is not.

The second class is the subclass to the base class. It implements its own constructor and calls the base constructor. The second part of the sub class is the concrete implementation of the virtual base class function.

I then have a third class that has its own constructor. This third class has a function whose function header contains a reference to the base class. This same function then tries to pass this reference to the abstract class and then .push_back() the reference into a vector of std::unique_ptr of this abstract class. (Because I cannot directly have a vector of abstract class instances.)

My issue is that I am currently unable to get a version of this code to compile.

I have been referencing some resources online to try to solve my problem.

pass unique_ptr as an object
https://stackoverflow.com/questions/8114276/how-do-i-pass-a-unique-ptr-argument-to-a-constructor-or-a-function

adding elements of a vector of a base class
https://stackoverflow.com/questions/31410858/adding-elements-to-stdvector-of-an-abstract-class

can't access derived class method from pointer of base class - not entirely relavent, but good knowledge
https://stackoverflow.com/questions/23489554/cant-access-derived-class-method-from-pointer-of-type-base-class

I have created a shortened version of this problem in an example C++ executable that does not compile.

Here is the file:


/*
This script demonstrates my dilemma of trying to pass a subclass object
as a parameter to a function that expects the base class, and then 
take that passed in object in the function and add it to a vector of that object 
in a completely different class.
*/

#include <iostream>
#include <memory>
#include <vector>

class Baseclass
{
    public:
        Baseclass(int i)
        {
            lala = i;
        }

    // subclass MUST implement this method.
    virtual int addme(int d) = 0;

    protected:
        int lala;
};

class Subclass : Baseclass
{
    public:
        Subclass(int d, int l) : Baseclass(d)
        {
            blahblah = l;
        }

        int addme(int d)
        {
            return blahblah + lala + d;
        }

    protected:
        int blahblah;
};

class Mainclass
{
    public:
        Mainclass(uint blah)
        {
            anotherone = blah;
        }

        // This is the function I cannot seem to get to work.
        // How can I make the function parameter an abstract class?
        // The object being passed in is NOT abstract...
        bool addController(Baseclass & basecont)
        {
            // This line here does NOT compile!!
            // controllers.push_back(std::make_unique<What goes here?>(basecont));
            return true;
        }

    protected:
        uint anotherone;
        std::vector<std::unique_ptr<Baseclass>> controllers;
};

int main(int argc , char ** argv)
{
    // create subclassed controllers
    Subclass cont1 = Subclass(12, 23);
    Subclass cont2 = Subclass(233, 2);
    // create main object
    Mainclass mainbro = Mainclass(23);
    // Add the subclased controllers to the main class
    // THESE 2 lines do not compile!!
    // mainbro.addController(cont1);
    // mainbro.addController(cont2);
    //
    return 0;
}

I figure that I am doing something very wrong, but I do not feel the process I outlined in itself is impossible. I just think that I am going about the problem wrong.

I have highlighted, in the script, where I am not sure what I should do and where the code breaks.

I may need to take an alternative approach to the problem, I just do not know what alternatives I have available.

Aucun commentaire:

Enregistrer un commentaire