指向派生类的指针的重载解析
Overload resolution for pointer to derived class
我会accept
指向基类的指针,然后根据其派生类型调用不同的函数。
[ 编辑
问题是:accept 是 Manager 类的公共方法,它处理和存储大量 A、B1、B2(shared_ptr(实例。管理器将根据运行时实际类型处理它们
编辑 ]
#include <memory>
#include <iostream>
class A {};
class B1 : public A {};
class B2 : public A {};
void accept(std::shared_ptr<B1> sp) { std::cout << "B1 "; }
// How to ensure the overload call to right derived type ?
void accept(std::shared_ptr<A> sp) {
std::cout << "A ";
// if runtime type of sp.get is B1, do something
// elif is B2, something else...
// then if is A, do another thing
}
void accept(std::shared_ptr<B2> sp) { std::cout << "B2 "; }
int main(int argc, char**argv)
{
auto a = std::make_shared<A>();
auto b1 = std::make_shared<B1>();
auto b2 = std::make_shared<B2>();
std::shared_ptr<A> ab2 = std::make_shared<B2>(): // !!!
accept(a);
accept(b1);
accept(b2);
accept(ab2); // !!!
}
输出A B1 B2 A
。我想B2
后者。
我误解了继承吗?
如果没有virtual
调度,重载解析在编译时执行,即基于对象的静态类型,而不是动态类型。因为ab2
是std::shared_ptr<A>
,所以选择A
重载。
若要涉及运行时类型信息(即对象的动态类型(,必须使用virtual
方法(和多态性(,而不是重载解析。目前尚不清楚如何最好地将其合并到给定的示例中。
最直接的方法是A
提供一个虚拟析构函数和一些虚拟方法(如在派生类中被覆盖的accept()
(,以显式调度到最合适的自由函数重载。不过还有其他方法,这取决于您的需求。
还应该注意的是,此代码中没有任何 SFINAE。
要重申和响应编辑,请执行以下操作: 如果要使用动态而不是静态类型信息,则类型必须至少有一个虚拟方法:
class A { virtual ~A(); };
如果你这样做,那么你可以使用例如dynamic_cast
(或者,由于您使用std::shared_ptr
、std::dynamic_pointer_cast
(来确定对象的运行时类型:
void accept(std::shared_ptr<B1> sp) { std::cout << "B1 "; }
void accept(std::shared_ptr<B2> sp) { std::cout << "B2 "; }
// How to ensure the overload call to right derived type ?
void accept(std::shared_ptr<A> sp) {
if (std::shared_ptr<B1> ptrB1 = std::dynamic_pointer_cast<B1>(sp))
accept(ptrB1);
else if (std::shared_ptr<B2> ptrB2 = std::dynamic_pointer_cast<B2>(sp))
accept(ptrB2);
else
// if is A, do another thing
}
但是,如果您像这样手动dynamic_cast
不同类型的类型,那么您可能没有正确的抽象。查看变体或访问者模式(或在一个新问题中询问此建议,详细说明您的问题和约束(。
相关文章:
- C++指针复制重载
- 如何在基类指针向量的元素上应用重载的多态函数
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 错误:表达式必须具有算术、无作用域枚举或带有运算符重载的指针类型
- 指向重载静态成员的函数指针 - 在unique_ptr中用作自定义删除器
- 重载 ostream << 运算符,指针作为参数,导致输出上的内存地址
- 使用类指针重载C++命名空间函数模板专用化替代方法?
- 类重载运算符 '<' 插入指向该对象集的共享指针时不调用
- 使用继承的指针列表复制构造函数或重载运算符=
- 为指针重载运算符++
- 如何从模板类重载创建的指针对象上的运算符?
- 指向派生类的指针的重载解析
- 重载解析、名称查找和函数指针
- 重载 >= 运算符来比较指针
- 如何获取指向未知重载函数的任何重载的指针?
- C++指针对象的运算符重载
- 使用空大括号初始值设定项的重载分辨率:指针还是引用?
- 指向结构的指针的运算符重载
- 指向函数的重载指针
- Visual Studio - C++:维基教科书中关于重载指针/引用相关运算符的代码无法编译