Generic base class with multiple template specialized derived classes

前端 未结 4 1002
梦如初夏
梦如初夏 2021-02-09 02:58

I have a finite amount of classes with the nearly-same implementation, the only different being the underlying type of data they manipulate:

class IntContainer
{         


        
4条回答
  •  南笙
    南笙 (楼主)
    2021-02-09 03:35

    Assuming you have some design flexibility, you can change your interface to accommodate this, although its not as efficient as an infinite virtual table

    You can set values through construction, or >>

    You can get values through <<

    Your vector needs to be a base pointer or reference, the size of each base object is variable, the pointer, explicit or implicit through a reference is of fixed size

    Notice that copies are more efficient if the compiler knows that it is copying from one generic to another as opposed to base to base

    #include 
    #include 
    #include 
    
    class gen_base
    {
    public:
        virtual std::ostream & output(std::ostream& S) const = 0;
        virtual std::istream & input(std::istream& S) = 0;
    
        friend std::istream & operator >> (std::istream &S, gen_base &g) {
            return g.input(S);
        }
    
        friend std::ostream & operator << (std::ostream &S, const gen_base &g) {
            return g.output(S);
        }
    };
    
    template
    class GenericContainer : public gen_base
    {
    public:
        GenericContainer(T data) : _data(data) {}
        GenericContainer(const gen_base& other) {
    // std::cout << "EXPENSIVE" << std::endl;
            std::stringstream cvt;
            other.output(cvt);
            input(cvt);
        }
        template 
        GenericContainer(const GenericContainer& other)
        {
    // std::cout << "CHEAP" << std::endl;
            _data=other.getData();
        }
        virtual std::istream & input(std::istream &S) {
            return (S >> _data);
        }
        virtual std::ostream & output(std::ostream &S) const {
            return (S << _data);
        }
        T getData() const {
          return _data;
        }
    private:
        T _data;
    };
    
    typedef GenericContainer IntContainer;
    typedef GenericContainer BoolContainer;
    typedef GenericContainer StringContainer;
    
    int main(int argc, char const *argv[])
    {
        IntContainer * intc = new IntContainer(42);
        std::cout << *intc << std::endl;
    
        gen_base * boolc = new BoolContainer(*intc);
        std::cout << *boolc << std::endl;
    
        IntContainer * intc2 = new IntContainer(*boolc);
        std::cout << *intc2 << std::endl;
    
        std::vector v; // has to be pointer to base;
        v.push_back(intc);
        v.push_back(boolc);
        v.push_back(intc2);
    
        for (std::vector::iterator it = v.begin() ; it != v.end(); ++it)
            std::cout << **it << std::endl;
    
        delete intc;
        delete boolc;
    
        return 0;
    }
    

提交回复
热议问题