简体   繁体   中英

Understanding inheritance on C++ template class

I am trying to design a C++ Template class which will contain all the features of a Tree (ie appendChild , childCount ). I want to then extend from this template class and design custom Tree class with existing features (read as Methods ) as well as extra features.

So far I got this.

#include <iostream>
#include <list>

/* TREE TEMPLATE CLASS */
template <class T>
class TreeTemplate
{
    public:
        TreeTemplate();
        void appendChild(T*);
        int getChildCount();
    protected:
        std::list<T*> m_childList;
};

/* Constuctor */
template <class T>
TreeTemplate<T>::TreeTemplate(){}

template <class T>
void TreeTemplate<T>::appendChild(T* t)
{
    m_childList.push_back(t);
}

template <class T>
int TreeTemplate<T>::getChildCount()
{
    return m_childList.size();
}

/* CLASS INHERITTING TEMPLATE */
class TreeItem : public TreeTemplate<TreeItem>
{
    public:
        std::string getTestName();
        TreeItem(std::string, std::string);

    private:
        std::string m_testID;
        std::string m_testName;
};

TreeItem::TreeItem(std::string test_id, std::string test_name)
{
    m_testID = test_id;
    m_testName = test_name;
}

std::string TreeItem::getTestName()
{
    return m_testName;
}

/* MAIN FUNCTION */
int main()
{
    TreeItem *myTree = new TreeItem("9", "10");
    TreeItem *child1 = new TreeItem("9.1", "10.1");
    TreeItem *child2 = new TreeItem();

    std::cout << myTree->getTestName() << std::endl;

    myTree->appendChild(child1);
    std::cout << myTree->getChildCount() << std::endl;
    return 0;
}

Now, if I don't try to add some new Constructor in derived class (ie contructor overload ), everything is good. But, if I am adding a new Constructor (as the code segment shows), I am failing to access the existing constructor (of Base Template class). I am getting following error in the line TreeItem *child2 = new TreeItem();

在此处输入图片说明

Am I doing something stupid here ? I can overload other methods, only failing at Constructor. How can I overload existing constructor of base template class?

There are two problems to address. The first is that when you define a constructor for a type, that type's default constructor is not implicitly generated. You can force it to be by using = default . Here is an example.

struct Foo {
    Foo() = default;    // Allows default construction
    Foo(int value) : m_value(value) {}
    int m_value;
};

The second problem is that a derived type does not inherit it's parent's class' constructors. Intuitively, in the following example, how can a constructor of type Base construct an instance of type Derived ? Base is not aware of Derived 's members.

class Base {
public:
    Base(int x, int y) : m_x(x), m_y(y) {}
private:
    int m_x;
    int m_y;
};

class Derived : public Base {
public:
    Derived(int x, int y, int z) : Base(x, y), m_z(z) {}
private:
    int m_z;
};

void foo()
{
    // If we use Base's constructor, what is m_z?
    // Won't compile
    Derived bar(1, 2);
}

Only the constructors of the type you are actually constructing are eligible, not it's base types' constructors. To simulate the behavior you will have to provide new constructors for the set of parameters you want to support.

class Derived : public Base {
public:
    Derived(int x, int y, int z) : Base(x, y), m_z(z) {}
    Derived(int x, int y) : Base(x, y), m_z(0) {}
private:
    int m_z;
};

In certain cases you can work around this problem by supplying a variadic template constructor like the following example. This shouldn't be done in general, only when there is a particular need.

#include <utility>

class Base {
public:
    Base(int x, int y) : m_x(x), m_y(y) {}
private:
    int m_x;
    int m_y;
};

class Derived : public Base {
public:
    template<class ... Args>
    Derived(Args&&... args) : Base(std::forward<Args>(args)...) {};
};

void foo()
{
    Derived b(1, 2);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM