首页 > 解决方案 > 使用子 C++ 从另一个函数调用父函数

问题描述

所以我有一个父类是:

class Node
{
public:
    Node();

    void setParentNode(Node* parent) {this->parentNode = parent;}
    Node* getParentNode() {return this->parentNode;}

    std::vector<Node> getChildNodes(){return this->childNodes;}

    void addChildNode(Node* node);
    void removeNode();

private:
    std::vector<Node*> childNodes;
    Node* parentNode = nullptr;
};

还有一个继承自该类的孩子:

class Cube : public Node
{
public:
    Cube();
};

现在我有另一个文件,它有一个使用子类的函数:

#include "cube.h"

void addCubes(){
     Cube mainCube;
     for(int i = 0; i < 10; i++){
         Cube c;
         mainCube.addChildNode(c);
      }
}

问题是 mainCube 没有看到父级的 addChildNode 函数。如果无法使用子类从另一个地方访问父函数,那么从另一个类继承有什么意义?

标签: c++inheritance

解决方案


如果您保持函数的签名对齐,派生类应该能够看到该addChildNode函数。这不是一个大问题。但是,您的代码还有一些“严重”的问题:

  1. 您需要将基类的析构函数设为虚拟以避免一些未定义的行为。

  2. 您必须仔细设计节点的所有权。我猜你希望 Node 类拥有和管理它的子节点。这意味着函数addChildNode实际上拥有传入的节点对象的所有权,并且它也应该在销毁期间被删除。

  3. 在 functionaddCubes()中,有一个循环不断调用addChildNode函数,但传递局部变量,该变量Cube c;将超出范围并在循环后销毁。因此,父对象mainCube将持有指向已销毁对象的指针,这将导致崩溃。

解决所有这些问题后,您的代码如下所示:

class Node
{
public:
    Node() {};
    virtual ~Node() {
        for(auto n: childNodes) delete n;
    };

    void setParentNode(Node* parent) {this->parentNode = parent;}
    Node* getParentNode() {return this->parentNode;}

    std::vector<Node*> getChildNodes(){return this->childNodes;}

    void addChildNode(Node* node) {
        childNodes.push_back(node);
    };
    void removeNode();

private:
    std::vector<Node*> childNodes;
    Node* parentNode = nullptr;
};

class Cube : public Node
{
public:
    Cube() {};
};

void addCubes(){
    Cube mainCube;
    for(int i = 0; i < 10; i++){
        Cube *c = new Cube();
        mainCube.addChildNode(c);
    }
}

优先使用智能指针来管理内存,代码更优雅,更容易阅读,也更难出错:-)。

#include <memory>

class Node
{
public:
    Node() {};
    virtual ~Node() {};

    void setParentNode(Node* parent) {this->parentNode = parent;}
    Node* getParentNode() {return this->parentNode;}

    std::vector<std::shared_ptr<Node>>& getChildNodes(){return this->childNodes;}

    void addChildNode(std::shared_ptr<Node> node) {
        childNodes.push_back(std::move(node));
    };
    void removeNode();

private:
    // childNodes own elements in it, they will be deleted automatically.
    std::vector<std::shared_ptr<Node>> childNodes;
    Node* parentNode = nullptr;
};
class Cube: public Node
{
public:
    Cube() {};
};
void addCubes(){
    Cube mainCube;
    for(int i = 0; i < 10; i++){
        auto c = std::make_unique<Cube>();
        mainCube.addChildNode(std::move(c));
    }
}

推荐阅读