【问题标题】:C++ nested class inheriting from nested class, type issueC++ 嵌套类继承自嵌套类,类型问题
【发布时间】:2017-07-22 12:23:12
【问题描述】:

我在尝试实现红黑树类时遇到了问题。我之前构建了一个二叉树类,所以我从它继承了我的红黑树。

二叉树声明如下:

template <typename KeyType, typename DataType>
class BTree{
protected:
    struct BTreeNode{
        KeyType key;
        DataType data;
        BTreeNode *left;
        BTreeNode *right;
        BTreeNode *parent;
        BTreeNode(const KeyType &Key, const DataType &Data);
    };
    BTreeNode *root;
    void clear(BTreeNode *root);

public:
    BTree();
    virtual ~BTree();

    virtual bool insert(const KeyType &Key, const DataType &Data);
    virtual bool erase(const KeyType &key);
    DataType &getFirst(const KeyType &Key);
    /**** some other methods ****/

}; // class bTree

而红黑树是这样的:

template <typename KeyType, typename DataType>
class RBTree : public BTree<KeyType, DataType>{
protected:
    struct RBTreeNode : BTree<KeyType, DataType>::BTreeNode{
        enum RB{red, black} rb;
        RBTreeNode(const KeyType &Key, const DataType &Data, RB Rb=red);
    };

private:
    void leftRotate(RBTreeNode *x);
    void rightRotate(RBTreeNode *x);

public:
    /**** some other methods ****/
}; // class RBTree

问题来了,当我实现RBTree::leftRotate()时,我必须写RBTreeNode *y = x-&gt;righty=y-&gt;left之类的东西,但是x-&gt;righty-&gt;leftBTreeNode *,并且不能自动转换为RBTreeNode * .

我不希望我的代码充满 static_cast&lt;RBTreeNode *&gt;(x) 之类的东西,而且我不想重新定义 RBTreeNode 或 RBTree 类,这意味着我必须重写 BTree 中的每个方法,例如我可以使用的 getFirst()直接。

那么我应该如何构造RBTree呢?我必须重写整个 RBTree 类吗?非常感谢。

【问题讨论】:

  • RBTreeNode 中,有一个类似RBTreeNode* right() { return static_cast&lt;RBTreeNode*&gt;(BTreeNode::right); } 的方法。然后使用x-&gt;right() 代替x-&gt;right
  • 谢谢。没想到……

标签: c++ inheritance type-conversion


【解决方案1】:

你可以使用这个技巧:

template <typename D>
struct Base{
    D *root;
};

struct Derived : Base<Derived>
{
};

int main()
{
    Derived x;
    x.root = 0;
    return 0;
}

我对您的示例进行了很多简化,并删除了所有额外的模板参数,这些参数对于说明这一点是不必要的。请注意,Base 类包含一个指向 Derived 类的指针,该指针作为模板参数传递给它。

在您的情况下,将一个模板参数 D 添加到您的基类,将基类指针定义为 D* 类型,当您定义派生类时,将派生类本身作为模板参数传递。例如。

template <typename KeyType, typename DataType>
class RBTree : public BTree<KeyType, DataType, RBTree<KeyType,DataType> >
{...}

这个主题有很多变体,例如,在您的情况下,您的模板参数可能是模板参数的模板。

当在基类中使用指向派生类的指针时,这个技巧很有效。如果在基类中有派生类的实际实例,除非派生类没有数据成员,否则这通常不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 2011-06-19
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多