重写虚函数 return 类型不同并且在数据结构中不是协变的

overriding virtual function return type differs and is not covariant in Data Structure

当我尝试编译时出现一个奇怪的错误:"overriding virtual function return type differs and is not covariant",我认为问题出在 Node.js 上。我认为 BTree<T>::NodeBSTree<T>::Node 不同。

基础class:

#ifndef BINARY_TREE_H
#define BINARY_TREE_H

template < typename T >
class BTree {
protected:
    struct Node {
        T key;
        Node* left;
        Node* right;

        Node() {}
        Node(
            const T& key,
            Node* left = nullptr,
            Node* right = nullptr)
            : left(left), right(right), key(key) {}
    };
public:
    BTree();
    virtual ~BTree();
    virtual Node* search(const T& key);


private:
    Node* search(const T& key, Node* root);

private:
    Node* root;
};

template < typename T >
typename BTree<T>::Node* BTree<T>::search(const T& key, BTree<T>::Node* root) {

    //some code
}

template < typename T >
typename BTree<T>::Node* BTree<T>::search(const T& key) {
    return search(key, root);
}

#endif // BINARY_TREE_H

派生 class:

#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H

#include "binary_tree.h"

template < typename T >
class BSTree : public BTree<T> {
protected:
    struct Node {
        T key;
        Node* left;
        Node* right;

        Node() {}
        Node(
            const T& key,
            Node* left = nullptr,
            Node* right = nullptr)
            : left(left), right(right), key(key) {}
    };
public:
    BSTree();
    ~BSTree() override;  
    Node* search(const T& key) override;

private:
    Node* search(const T& key, Node* root);

private:
    Node* root;
};

template < typename T >
typename BSTree<T>::Node* BSTree<T>::search(const T& key, BSTree<T>::Node* root) {
    //some code
}

template < typename T >
typename BSTree<T>::Node* BSTree<T>::search(const T& key) {
    return search(key, root);
}

#endif // BINARY_SEARCH_TREE_H

虽然BSTree<T>源自BTree<T>,但BSTree<T>::NodeBTree<T>::Node之间没有关系。因此,指向后者的指针不能转换为指向前者的指针。 BTree<T>::search return 是指向 BTree<T>::Node 的指针。因此,在派生的 class 中对该函数的任何覆盖都必须 return 一个指针,该指针可以 转换 BTree<T>::Node*.

如前所述,BSTree<T>::Node* 不是。

真的,如果 BSTree<T>::NodeBTree<T>::Node 做同样的事情,为什么还要存在?

这是正确的代码。请注意在看到 BTree<T>::Node.

之前添加 typename

基础class:

#ifndef BINARY_TREE_HPP
#define BINARY_TREE_HPP

template < typename T >
class BTree {
protected:
    struct Node {
        int key;
        Node* left;
        Node* right;

        Node() {}
        Node(
            const int& key,
            Node* left = nullptr,
            Node* right = nullptr)
            : left(left), right(right), key(key) {}
    };
public:
    BTree();
    virtual ~BTree();    
    virtual Node* search(const T& key);

private:
    Node* search(const T& key, Node* root);

private:
    Node* root;
};

template < typename T >
typename BTree<T>::Node* BTree<T>::search(const T& key, BTree<T>::Node* root) {

    // some code
}

template < typename T >
typename BTree<T>::Node* BTree<T>::search(const T& key) {
    return search(key, root);
}

派生 class:

#ifndef BINARY_SEARCH_TREE_HPP
#define BINARY_SEARCH_TREE_HPP

#include "binary_tree.hpp"

template < typename T >
class BSTree : public BTree<T> {
public:
    BSTree();
    ~BSTree() override;
    typename BTree<T>::Node* search(const T& key) override;

private:
    typename BTree<T>::Node* search(const T& key, typename BTree<T>::Node* root);

private:
    typename BTree<T>::Node* root;

};

template < typename T >
typename BTree<T>::Node* BSTree<T>::search(const T& key, typename BTree<T>::Node* root) {

    // some code
}

template < typename T >
typename BTree<T>::Node* BSTree<T>::search(const T& key) {
    return search(key, root);
}