从基类的唯一指针中声明派生类的类型
Decltype of derived class from unique pointer to base class
我想进行运行时多态性,并且必须知道实际类型,例如计算某个派生类的实例。以下是我目前所拥有的:
标题
struct Base {
virtual ~Base();
};
struct DerivedFoo : public Base {};
struct DerivedBar : public Base {};
源
Base::~Base() {}
int main() {
std::vector<std::unique_ptr<Base>> my_array{};
my_array.emplace_back(std::make_unique<DerivedFoo>());
my_array.emplace_back(std::make_unique<DerivedBar>());
for (const auto& elem : my_array) {
if (std::is_same<DerivedFoo, decltype(elem)>::value) {
// do something
}
// some testing
std::cout << typeid(decltype(elem)).name() << 'n';
std::cout << typeid(decltype(*elem)).name() << 'n';
std::cout << typeid(decltype(*elem.get())).name() << 'n';
}
return 0;
}
输出
St10unique_ptrI4BaseSt14default_deleteIS0_EE
4Base
4Base
St10unique_ptrI4BaseSt14default_deleteIS0_EE
4Base
4Base
问题是:我只设法得到基类的类型。不是派生的。所以我从不输入if语句。
- 我可以添加一个虚拟函数"GetID(("或类似的函数。但我觉得这是多余的。我应该能够用类型特征来做到这一点
- 我查看了
std::unique_pointer<...>::element_type
和std::pointer_traits
,但无法使其运行
有什么想法吗?
代码中的问题是期望运行时多态性,但只使用编译时类型:
decltype(x)
提供了x的编译时类型- 所以
typeid(decltype(x))
是指编译时类型的运行时类型信息,所以在您的示例中是4Base
如果要使用运行时类型,请直接在对象上使用typeid
,如下所示:
std::cout <<< typeid(elem).name() << 'n';
std::cout << typeid(*elem).name() << 'n';
std::cout << typeid(*elem.get()).name() << 'n';
结果看起来像:
St10unique_ptrI4BaseSt14default_deleteIS0_EE
10DerivedFoo
10DerivedFoo
St10unique_ptrI4BaseSt14default_deleteIS0_EE
10DerivedBar
10DerivedBar
同样,std::is_same<DerivedFoo, decltype(elem)>::value
是基于模板类型推导的,所以再次编译。如果您想在运行时对多态类型进行检查,则需要使用以下构造:
if (dynamic_cast<DerivedFoo*>(&*elem)) {
// do something
}
使用访问者模式
struct Counter;
struct Foo;
struct Bar;
struct BarBar;
struct Counter {
int barCount = 0;
int barBarCount = 0;
void visit(Bar *bar) {
barCount += 1;
}
void visit(BarBar *bar) {
barBarCount += 1;
}
};
struct Foo {
virtual void accept(Counter* v) = 0;
};
struct Bar : public Foo {
void accept(Counter* v) override {
v->visit(this);
}
};
struct BarBar : public Foo {
void accept(Counter* v) override {
v->visit(this);
}
};
int main()
{
std::vector<std::unique_ptr<Foo>> foos;
foos.emplace_back(std::make_unique<Bar>());
foos.emplace_back(std::make_unique<BarBar>());
Counter counter;
for(const auto& foo : foos) {
foo->accept(&counter);
}
std::cout << counter.barCount << " " << counter.barBarCount << std::endl;
}
输出1 1
相关文章:
- 具有多个类、派生类的C++正向声明
- 是否可以使用 using 将基类中的公共成员重新声明为派生类中的私有成员?
- 基类可以声明虚拟方法但不定义它吗?仍然在派生类中定义
- 将派生类的构造函数声明为父类的友元
- 从模板基类派生是否在派生类声明的点实例化模板
- 从基类的唯一指针中声明派生类的类型
- C++ 多态性:如果派生类中的虚函数在基类中声明了常量,是否需要将其声明为常量
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- 如何声明从 QApplication 派生的 Qt 类并覆盖通知函数?
- 是否可以在引用另一个派生类的派生类中声明复制构造函数?
- 冲突的声明(外部基础与派生)
- 声明派生类的对象而不指定它
- 通过派生类模板参数指定基类模板参数之一。如何使用基类的 using 声明
- 声明嵌套基模板类实例是派生类的好友
- 是否可以在C++中声明基类,以便只能通过创建函数创建从它派生的类
- 在基类主体内声明但通过派生类召集的函数
- 如何在基本模板类中声明成员,其中类型取决于派生类的类型
- 在派生的C 类中,访问基类受保护成员作为公共的访问声明
- 在基类中使用派生类,而在基类之后声明派生类
- 在派生类或基类中,我应该在哪里声明友元类