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

时间:2019-06-07 16:43:54

标签: c++ pointers sparse-matrix

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

我“用google搜索”了我的问题,发现存在一些铸造问题。我尝试了一下,也没有用。

示例代码:

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';

2 个答案:

答案 0 :(得分:3)

root是一个节点指针。 root->right是另一个节点指针。 root->right->down是-您猜到了-一个Node指针。

当您执行[...]->value时,您将取消引用该Node指针,该指针为您提供一个Node,然后尝试在其上获取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均为非空,然后再取消引用它们。

答案 1 :(得分:1)

根类Node仅具有指向其他Node的指针,因为它不知道它们可能是什么派生类。

“通常”最好在基类中具有正确的接口,以从不同种类的派生类中获取结果/值。

例如,如果您有一个基类动物:

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

然后是派生类的猪:

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

通过这样做,类的“接口”是通用的,但是每个派生/专业化的类都可以具有特定的值。

在您的情况下,您可能只需要在基类中使用一个名为virtual int get_value()的函数,然后在您的ENode类中实现该函数即可...

(请注意,以上所有代码仅是伪代码)