如何访问存储在父 class 中的子 class 成员?

How can I access a child class member stored in a parent class?

我被分配创建一个稀疏矩阵。在这个过程中,我遇到了一个问题。我意识到我无法访问存储在父 class.

中的子 class 的成员

我 'googled' 我的问题是我遇到了一些铸造问题。我试了一下也没用。

示例代码:

main.cpp

#include <iostream>

template <typename T>
class Node
{
public:                     // public for example purposes
    Node<T> *down, *right;

public:
    explicit Node(Node<T> *d, Node<T> *r) : down(d), right(r) {}
};

template <typename T>
class HNode : public Node<T>
{
private:
    unsigned idxValue;

public:
    HNode(unsigned iv) : idxValue(iv), Node<T>(nullptr, nullptr) {}
};

template <typename T>
class ENode : public Node<T>
{
public:                     // public for example purposes
    unsigned row;
    unsigned col;
    int value;

public:
    ENode(unsigned r, unsigned c, int v) : row(r), col(c), value(v), Node<T>(nullptr, nullptr)
    {}
};

int main(void)
{
    Node<int> *root;

    root = new Node<int>(nullptr, nullptr);

    root->right = new HNode<int>(0);
    root->down = new HNode<int>(0);
    root->right->down = new ENode<int>(0, 0, 10);


    std::cout << root->right->down->value << '\n';
}

这是我得到的错误:

error: no member named 'value' in 'Node<int>'
std::cout << root->right->down->value << '\n';

根 class Node 只有指向其他 Node 的指针,它不知道它们可能是什么派生的 classes。

最好 "usually" 在基 class 中有正确的接口,以便从不同类型的派生 classes 中得到 results/values。

例如,如果你有一个基础 class 动物:

class animal
{
    virtual int number_of_limbs() = 0;
}

然后导出class猪:

class pig: public animal
{
   int number_of_limbs() override { return 3;}
}

通过这样做,"interface" 到 class 是通用的,但每个 derived/specialisation 都可以具有特定的值。

在你的情况下,你可能只需要在你的基础 class 中调用一个名为 virtual int get_value() 的函数,然后在你的 ENode class...[=16 中实现它=]

(注意以上代码均为伪代码)

root 是一个节点指针。 root->right 是另一个节点指针。 root->right->down 是——你猜对了——一个节点指针。

当您执行 [...]->value 时,您将取消引用该节点指针,这会为您提供一个节点,然后尝试获取其上的 value 成员。但是Node没有value个成员!

可以尝试使用动态转换将您的 Node 指针转换为 ENode 指针。看起来像:

Node *n = root->right->down;
if(ENode *en = dynamic_cast<ENode*>(n)) {
    std::cout << en->value << std::endl;
} else {
    std::cout << "That's not an ENode!" << std::endl;
}

但是要做到这一点,你需要让 Node 多态化(你可以看到详细的here)。

另请注意,在生产代码中,您应该检查以确保 rootroot->rightroot->right->down 都是 non-null,然后再继续并取消引用它们。