C++ 使用子C+;从另一个函数调用父函数+;

C++ 使用子C+;从另一个函数调用父函数+;,c++,inheritance,C++,Inheritance,所以我有一个父类,它是: class Node { public: Node(); void setParentNode(Node* parent) {this->parentNode = parent;} Node* getParentNode() {return this->parentNode;} std::vector<Node> getChildNodes(){return this->childNodes;}

所以我有一个父类,它是:

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;
};
现在我有了另一个文件,它有一个使用子类的函数:

#include "cube.h"

void addCubes(){
     Cube mainCube;
     for(int i = 0; i < 10; i++){
         Cube c;
         mainCube.addChildNode(c);
      }
}
#包括“cube.h”
void addCubes(){
立方体主立方体;
对于(int i=0;i<10;i++){
立方体c;
mainCube.addChildNode(c);
}
}

问题是mainCube没有看到父节点具有的addChildNode函数。如果不能使用子类从其他位置访问父类函数,那么从其他类继承有什么意义?

否,父类公共函数可以从子对象调用。 然而,该函数的原型是

void Node::addChildNode(Node node);
所以它采用的是
节点
对象&而不是
立方体
对象。 因此,编译器找不到接受
Cube
对象的函数&因此出现错误

修复方法是在声明/定义函数时使用指向
节点
的指针或对
节点
的引用

所以你的函数应该是

void addChildNode(Node & node);
在这种情况下,节点对象可以传递给函数&编译器将找到它

最好是

// if you aren't looking to modify the passed object inside addChildNode
void addChildNode(const Node & node); 
以下是很好的&因此该函数将起作用

Cube b;   
Node &a = b;


不,父类公共函数可以从子对象调用。 然而,该函数的原型是

void Node::addChildNode(Node node);
所以它采用的是
节点
对象&而不是
立方体
对象。 因此,编译器找不到接受
Cube
对象的函数&因此出现错误

修复方法是在声明/定义函数时使用指向
节点
的指针或对
节点
的引用

所以你的函数应该是

void addChildNode(Node & node);
在这种情况下,节点对象可以传递给函数&编译器将找到它

最好是

// if you aren't looking to modify the passed object inside addChildNode
void addChildNode(const Node & node); 
以下是很好的&因此该函数将起作用

Cube b;   
Node &a = b;


假设您已经共享了代码的整个实现。您尚未定义函数体
addChildNode
,类似于
setParentNode
等。您需要执行类似于
childNodes的操作。向后推(node)在该函数中


注意:还需要将输入传递到@user93353的答案中所示的
addChildNode
。另外,将
childNodes
定义为
std::vector
,以避免对象切片。

假设您共享了代码的整个实现。您尚未定义函数体
addChildNode
,类似于
setParentNode
等。您需要执行类似于
childNodes的操作。向后推(node)在该函数中


注意:还需要将输入传递到@user93353的答案中所示的
addChildNode
。另外,将
childNodes
定义为
std::vector
,以避免对象切片。

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

  • 您需要使基类的析构函数为虚拟的,以避免一些未定义的行为

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

  • 在函数
    addCubes()
    中,有一个循环不断调用
    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);
        }
    }
    
    类节点
    {
    公众:
    Node(){};
    虚拟节点(){
    对于(自动n:子节点)删除n;
    };
    void setParentNode(Node*parent){this->parentNode=parent;}
    Node*getParentNode(){返回此->parentNode;}
    std::vector getChildNodes(){返回此->childNodes;}
    void addChildNode(节点*节点){
    childNodes.push_back(节点);
    };
    void removeNode();
    私人:
    std::向量子节点;
    Node*parentNode=nullptr;
    };
    类多维数据集:公共节点
    {
    公众:
    立方体(){};
    };
    void addCubes(){
    立方体主立方体;
    对于(int i=0;i<10;i++){
    多维数据集*c=新多维数据集();
    mainCube.addChildNode(c);
    }
    }
    
    最好使用智能指针来管理内存,代码更优雅、更易于阅读,并且更难出错:-)

    #包括
    类节点
    {
    公众:
    Node(){};
    虚拟~Node(){};
    void setParentNode(Node*parent){this->parentNode=parent;}
    Node*getParentNode(){返回此->parentNode;}
    std::vector&getChildNodes(){返回此->childNodes;}
    void addChildNode(std::shared\u ptr节点){
    向后推(std::move(node));
    };
    void removeNode();
    私人:
    //子节点拥有其中的元素,它们将被自动删除。
    std::向量子节点;
    Node*parentNode=nullptr;
    };
    类多维数据集:公共节点
    {
    公众:
    立方体(){};
    };
    void addCubes(){
    立方体主立方体;
    对于(int i=0;i<10;i++){
    自动c=std::使_唯一();
    addChildNode(std::move(c));
    }
    }
    
    如果保持函数签名对齐,则派生类应该能够看到
    addChildNode
    函数。这不是什么大问题。但是,您的代码还有一些更“严重”的问题:

  • 您需要使基类的析构函数为虚拟的,以避免一些未定义的行为

  • 您必须仔细设计节点的所有权。我猜您希望Node类拥有并管理其ch