c++中抽象类作为类型,派生类作为实例
Abstract class as a type, derived class as instance in C++
我试图为二叉树(每次遍历一个)创建3个迭代器(3个类),我希望它们共享相同的基类。
class BinaryTree
{
class Iterator
{
virtual Iterator operator++() = 0;
}
class Iterator1 : public Iterator
{
}
class Iterator2 : public Iterator
{
}
class Iterator3 : public Iterator
{
}
}
我已经实现了它们在Iterator类中共享的方法。唯一不同的方法是构造函数和前缀++的重载。
我的想法是使重载的操作符++成为虚函数,这样它就可以被Iterator1、2和3覆盖,因为我想这样使用迭代器:
for(BinaryTree::Iterator it = t.begin(Preorder); it != t.end(); it++)
{
// do stuff
}
我习惯了Java,在那里你可以创建一个抽象类型的对象,但将它实例化为另一种类型。问题是在c++中它是cannot allocate an object of abstract type
。begin
方法使用工厂模式:它返回一个迭代器1、2或3类型的对象。
是否有任何方法来保持与for
相同的语法?
请记住,在Java中,您不直接处理对象,而是使用指向对象的指针。在c++中,当您声明x
类型的变量时,您有一个x
,而不是从x
派生的东西。如果你想使用多态性,你需要一个引用(x&
)或一个指针(x*
, shared_ptr<x>
, unique_ptr<x>
,…)。
for循环应该是
for(BinaryTree::Iterator& it = t.begin_preorder(); it != t.end; it++)
并且BinaryTree::begin_preorder()
应该返回BinaryTree::Iterator#
,其中#
是对应于正确迭代器的数字。它不能返回BinaryTree::Iterator
,因为您不能拥有该类型的对象(它是抽象的)。如果它返回BinaryTree::Iterator&
,那么您将无法返回在函数中创建的(本地)对象,因为一旦函数退出,该对象将不再存在。如果您返回一个引用,那么引用指向的实际对象必须缓存在t
对象中。
我假设你想使用多态性,因为你不一定在编译时知道你要使用哪个迭代器(因为如果你在编译时知道,多态性是不必要的)。
如果您只是想在for循环中节省一些类型,并且不需要多态性:
for(auto it = t.begin_preorder(); it != t.end; it++)
可以正常工作。那么就不需要基类或虚成员函数了。
你需要对多态类型使用指针或引用:
struct Test {
struct Iterator {
virtual Iterator &operator++() = 0;
virtual ~Iterator() = 0;
};
struct Forward : public Iterator {
int i;
virtual Iterator &operator++()
{
i++;
return *this;
}
};
Iterator *forward()
{
return new Forward();
}
};
int main()
{
Test t;
Test::Iterator &it = *t.forward();
++it;
delete ⁢
}
通过将多态性隐藏在非多态包装器类(pimpl,或句柄体习惯用法)后面,可以使这些东西更像常规迭代器那样工作:
class IteratorImpl {
virtual IteratorImpl *clone() = 0;
virtual void increment() = 0;
virtual ~IteratorImpl() = 0;
};
// concrete subclasses
class iterator {
std::unique_ptr<IteratorImpl> impl;
public:
// operator++() based on IteratorImpl::increment
// copy constructor based on IteratorImpl::clone
};
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 如何检查派生类的类型?(C++实例)
- 从基类实例调用派生类方法而不进行强制转换
- 为什么派生类的实例从基类调用方法?
- 将基本实例指针强制转换为派生实例指针是否合法?(实例不是派生实例)
- 从模板基类派生是否在派生类声明的点实例化模板
- 选择专用于派生实例的基类的类模板
- 为什么我无法使用受保护/私有继承访问派生实例中基类的受保护成员?
- 派生实例不是指针时的基类的异构容器
- 我可以从 C++ 中的派生实例访问指向基本实例的指针吗?
- 如何在派生实例化之前创建抽象类
- 为什么可以从派生实例访问基类中的受保护变量
- C++-虚拟运算符=在派生实例的基类上调用
- 有没有一种方法可以从基本实例创建派生实例
- 将基类实例分配给c++中的派生实例
- 在c++中基类销毁期间是否有可能知道派生实例类型?
- 如何继承成员函数,使其始终返回对派生实例的引用
- 内存共享;继承;基实例和派生实例;c++
- C++:从派生实例调用 base 中的纯虚拟方法重载