从内部类继承
Inheritance from inner class
我在C++中实现了一个二叉搜索树,现在我正在尝试从中继承。
基础树:
#ifndef TREE_HPP
#define TREE_HPP
class tree {
public:
class node {
public:
virtual int foo() { return 1; }
node() = default;
virtual ~node() = default;
};
node* root;
tree() : root(new node) {}
virtual ~tree() { delete root; }
};
#endif
派生树:
#ifndef DERIVED_TREE_HPP
#define DERIVED_TREE_HPP
#include "tree.hpp"
class derivedTree : public tree {
public:
class derivedNode : public node {
public:
virtual int foo() { return 2; }
};
};
#endif
主要:
#include "derivedTree.hpp"
#include "tree.hpp"
#include <iostream>
using std::cout;
int main() {
tree t1;
derivedTree t2;
cout << "Hey! " << t1.root->foo() << "n";
cout << "Hey! " << t2.root->foo() << "n";
}
输出为:
Hey! 1
Hey! 1
我希望它是 1 和 2。 我认为这是因为root
是指向基础树的指针,因此调用tree::foo()
.如何从树继承,使其包含派生节点?
欢迎来到 StackOverflow!
虚拟方法的作用是使您能够根据实例化的实际类而不是指针的类型来调用方法。
因此,在您的情况下,root->foo()
会根据实际类调用该方法,而不是总是调用node
实现。
但是,要调用derivedNode
实现,您必须实例化它!就像现在一样,您的derivedTree
正在使用直接实例化node
的tree
的基本构造函数,因此derivedTree
和tree
都将有一个node
对象作为root
!
为了解决这个问题,如其他答案所示,您可以向tree
添加一个接受外部node
指针的构造函数,并在derivedTree
的构造函数中使用该构造函数,以使用指向derivedTree
的指针初始化root
。
像这样:(可运行的链接(
class tree {
public:
class node {
public:
virtual int foo() { return 1; }
node() = default;
virtual ~node() = default;
};
node* root;
tree(): root(new node) {};
tree(node* d) : root(d) {}; // here we initialize the root pointer with a given pointer
virtual ~tree() { delete root; };
};
class derivedTree : public tree {
public:
class derivedNode : public node {
public:
virtual int foo() { return 2; }
};
derivedTree(): tree(new derivedNode) {}; // here we use the added constructor to create a derivedNode and set it as root
};
using std::cout;
int main() {
tree t1;
derivedTree t2;
cout << "Hey! " << t1.root->foo() << "n";
cout << "Hey! " << t2.root->foo() << "n";
}
请注意,无法直接在派生构造函数中初始化root
,因为该语言允许在初始值设定项列表中仅放置实际类的字段而不是派生字段,并且根据编译器的不同,您将有创建内存泄漏的风险。
您可以添加另一个构造函数,该构造函数采用node*
类型的指针用于tree
,并使用该参数初始化root
。然后,您可以传递相应的指针。例如
class tree {
public:
...
tree(node* r) : root(r) {}
};
class derivedTree : public tree {
public:
...
derivedTree() : tree(new derivedNode) {}
};
住
您遇到的问题不在于继承,而在于嵌入node
对象而不是derivedNode
的tree
对象。
我会为此使用模板,类似于这些内容:
template <typename NodeType>
class treeT {
public:
NodeType* root;
tree() : root(new NodeType) {}
virtual ~tree() { delete root; }
};
class node {
public:
virtual int foo() { return 1; }
node() = default;
virtual ~node() = default;
};
class derivedNode : public node {
public:
virtual int foo() { return 2; }
};
using tree = treeT<node>;
using derivedTree = treeT<derivedNode>;
如果你真的想要内部类,你可以使用一种CRTP,但我想这将是过度工程化。
请注意,@songyuanyao也有一个很好的解决方案。我真的不能给你一个选择一种或另一种解决方案的理由。
- 在设计 SDK 时,我是否应该在 C++ 头文件中完全隐藏内部类?
- 如何声明由多个线程调用的 C++ DLL 的内部类,而无需导出类
- 从内部类继承
- 如何将枚举类转发声明为模板化类的内部类?
- 从内部类中的方法从包含类调用方法
- 从模板化父类中的派生内部类访问受保护的成员变量
- C++模板类的内部类访问
- 使用类模板的内部类模板专用化模板
- 如何使用包含内部类的类实例有效地从内部类访问成员?
- C++ 如何在外部类中声明的内部类中使用变量
- 在C++中将内部类实现为具有名称空间的独立类有什么好处
- 参数化类的别名(或类型定义)内部类
- 从内部类的析构函数调用虚拟函数
- 如何在没有setter的情况下设置类内部类的成员变量?
- 具有相同名称的方法和内部类(错误:.. 与前面的声明冲突)
- 内部类私有成员访问和封闭的友好性
- 在C++中从内部类对象获取外部类对象
- 生成文件 - 继承的类和内部类
- 使用内部类继承模板类,并访问继承类中的内部类
- 从具有私有内部类的类继承