c++ - 我可以限制多态性的行为吗?
问题描述
所以我正在尝试实现二叉搜索树和avl树。这些类中的每一个都使用不同但相似类型的节点。节点的类如下所示:
class node
{
protected:
int key;
node* parent, * left, * right;
public:
node(int key, node* parent = nullptr) :key(key), parent(parent), left(nullptr), right(nullptr) {}
~node() {}
};
class avl_node : public node
{
private:
int height;
public:
avl_node(int key, int height, avl_node* parent = nullptr) :node(key, parent), height(height) {}
~avl_node() {}
};
这主要是有效的。Anynode
可以与 any other 有联系node
,并且 anyavl_node
与 any other有联系avl_node
。我想到的问题是,由于多态性,anode
在技术上可能有一个或多个父avl_node
级,我不希望这种情况发生。虽然我可以通过小心来避免这种情况,但我根本不希望它成为可能。有办法吗?
ps我想保持类相关
解决方案
如果足够,您可以显式删除将采用的构造函数版本avl_node*
class node
{
protected:
int key;
node* parent, * left, * right;
public:
node(int key, node* parent = nullptr) :key(key), parent(parent), left(nullptr), right(nullptr) {}
node(int, avl_node*) = delete;
~node() {}
};
当然,这种解决方案并非万无一失。如果您在指针avl_node
后面带了一个隐藏node
项,编译器将无法分辨(并且由于多态性主要是动态的,因此您只会在尝试直接分配指针的特定情况下受到保护)
这将编译。
avl_node myavl;
node n(0, static_cast<node*>(&myavl));
您可以尝试在node
构造函数中进行动态转换以判断它是否avl_node
被传递(您的节点需要一个 vtable),但这将使得无法从avl_node
构造函数中调用构造函数。
另一种选择是制作一个专门用于子类的单独构造函数
class node
{
protected:
int key;
node* parent, * left, * right;
node(int key, avl_node* parent) : key(key), parent(parent), left(nullptr), right(nullptr) {}
public:
node(int key, node* parent = nullptr) :key(key), parent(parent), left(nullptr), right(nullptr) { /* do something to not allow avl_node* to be passed */ }
~node() {}
};
推荐阅读
- c# - 修改 Selenium 测试框架中的标头
- oop - 面向对象编程理论
- python - 如何重命名 pytest Allure 报告标题
- android - 如何在 React Native MapView 中调用方法?
- php - Codeigniter HMVC 登录只是不断重新加载
- c++ - 在带有 Eigen 的 C++ 中使用 GDB 时,我如何才能看到更多的大矩阵?
- firebase - 使用 Firestore 布尔值设置开关的值
- parallel-processing - 使用 pyarrow 和 s3 的 dask 计算出现不同的错误
- git - Github ssh -T git@github.com 显示旧用户名无处可寻
- matlab - 我在哪里可以在 simulink 中找到这两个块?