Derived Class with Derived Member Object

I want to have a base class that contains a member object. When I extend the base class, I want the member object to be of a type derived from the original type. I can do that with the following strategy. (Note: Please ignore my horrendous style. The code was formatted for space.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
using namespace std;  // for brevity

struct Helper
{
    virtual void bar() { cout << "Helper bar()" << endl; }
};

struct ExtendedHelper : Helper
{
    virtual void bar() { Helper::bar(); cout << "Extension..." << endl; }
};

struct BaseClass
{
    virtual void foo() { cout << "Class foo" << endl;  h_ref.bar(); }
    protected: BaseClass(Helper& h) : h_ref(h) {}
    private: Helper& h_ref;
};

struct NormalClass : BaseClass
{
    NormalClass() : BaseClass(helper) {}
    private: Helper helper;
};

struct ExtendedClass : BaseClass
{
    ExtendedClass() : BaseClass(extHelper) {}
    virtual void foo() { cout << "Extended foo" << endl; BaseClass::foo(); }
    private: ExtendedHelper extHelper;
};

int main()
{
    NormalClass().foo();
    std::cout << std::endl;
    ExtendedClass().foo();
}


I would like to do this without the "NormalClass". Semantically, there is a class with certain behavior, and an extension of the class with enhanced behavior. A 3rd class with the sole purpose of providing the default member object to the base class causes confusion.

Can I use a member object (not reference) in the BaseClass and replace this member object with an object of a derived class in the ExstendedClass?
How about
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Base{
protected:
    std::unique_ptr<Helper> helper;
    template <typename T>
    static std::unique_ptr<Helper> allocate_helper(){
        return std::make_unique<T>();
    }
    Base(std::unique_ptr<Helper> (*allocator)()): helper(allocator()){}
public:
    Base(): helper(allocate_helper<Helper>()){}
};

class Derived : public Base{
public:
    Derived(): Base(Base::allocate_helper<ExtendedHelper>){}
};
?
Last edited on
Thanks! That's what I was looking for.
Topic archived. No new replies allowed.