从基类调用指定的方法
Call specified method from base class
不知道如何很好地解释它,所以我只提供一个显示我的问题的代码示例:
class Base {
public:
Base() = default;
~Base() = default;
virtual void stuff(std::shared_ptr<Base> b) = 0;
};
class DerivedA : public Base {
public:
DerivedA() = default;
~DerivedA() = default;
void stuff(std::shared_ptr<Base> b) {
std::cout << "stuff Base"
<< "n";
}
};
class DerivedB : public Base {
public:
DerivedB() = default;
~DerivedB() = default;
void stuff(std::shared_ptr<Base> b) {
std::cout << "stuff Base"
<< "n";
}
void stuff(std::shared_ptr<DerivedA> b) {
std::cout << "stuff Derived"
<< "n";
}
};
int main(int argc, char *argv[]) {
std::shared_ptr<Base> b1(new DerivedA());
std::shared_ptr<Base> b2(new DerivedB());
b1->stuff(b2);
b2->stuff(b1);
return 0;
}
输出为:
stuff Base
stuff Base
现在,我想不可能调用派生方法,因为它不存在于基类中。
我的问题是:有没有一种方法可以使用基类调用stuff(std::shared_ptr<DerivedA> b)
?
[编辑]
我已经考虑过访客模式(应该说得更具体一些)。
我的类代表实体,我必须检查它们之间的冲突。然而,a&B将具有不同于B&C.
我同意它会起作用,但这意味着我必须定义大量的方法。
有更优雅的方法吗?
提前谢谢。
您要查找的通常称为多重调度或多重方法。C++中没有直接的语言支持,但您可以自己显式地实现它。基本上,您有一个虚拟函数,该函数将分派给另一个具有具体对象的虚拟函数:
struct DerivedA;
struct DerivedB;
struct Base {
virtual ~Base() = default;
virtual void stuff(shared_ptr<Base> ) = 0;
virtual void dispatch_stuff(Base& ) = 0;
virtual void dispatch_stuff(DerivedA& p) { return dispatch_stuff(static_cast<Base&>(p)); }
virtual void dispatch_stuff(DerivedB& p) { return dispatch_stuff(static_cast<Base&>(p)); }
struct DerivedA : Base {
void stuff(shared_ptr<Base> rhs) override {
rhs->dispatch_stuff(*this);
}
void dispatch_stuff(Base& ) { /* default */ }
void dispatch_stuff(DerivedA& ) { /* specific A-A stuff */ }
};
这样:
b1->stuff(b2); // calls b2->dispatch_stuff(DerivedA& )
b2->stuff(b1); // calls b1->dispatch_stuff(DerivedB& )
我的问题是:有没有办法打电话
stuff(std::shared_ptr<DerivedA> b)
使用基类?
不,因为Base
类接口没有实现您要调用的方法。即使Base
类指针引用的是DerivedB
对象,并且通过poilformism,您可以根据指针指向的对象类型(即DerivedB)来解析方法,但您只能调用Base
类中定义的方法。因此,不能使用指向DerivedB
对象的Base
指针来调用stuff(std::shared_ptr<DerivedA> b)
。
例如:
std::shared_ptr<Base> b1(new DerivedA());
std::shared_ptr<Base> b2(new DerivedB());
std::shared_ptr<DerivedA> a1(new DerivedA());
std::shared_ptr<DerivedB> bb1(new DerivedB());
b1->stuff(b2);
b2->stuff(b1);
b2->stuff(a1); // b2 is the only class that implement stuff(std::shared_ptr<DerivedA> b)
bb1->stuff(a1)
输出:
stuff Base
stuff Base
stuff Base
stuff Derived
stuff Base
您试图解决的问题称为双重调度问题,这意味着您试图根据两个对象的具体类型调用行为。在谷歌或这里查找这个术语可能会给你带来一些有趣的结果。
首先,不管怎样,你必须写很多函数,因为如果你有N个不同的类型,就有N个可能的配对。(如果顺序无关紧要,则NN/2,这可能是碰撞场景中的情况)。
访问者模式是双重调度问题的典型解决方案之一。
还有其他的,这取决于对你来说重要的是什么。例如,在我的脑海中,如果子类型的数量是有限的,并且在编译时是已知的,那么例如,您可以为每种类型都有一个索引和一个要调用的函数指针的2D数组(既不太优雅,也不太面向对象,但在性能方面相当高效)。
如果您担心函数的数量可能会导致代码重复,您可以始终将函数或类(类似CollisionPairBehavior
)中的代码考虑在内。
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 为什么此派生对象无法访问基类的后递减方法?
- 使用基类中的派生方法运行线程,而无需使用模板
- 将子类方法声明为基类的友元
- 是否可以使用基类非虚拟方法中的派生类虚拟方法?
- 在派生类中使用基类的私有成员变量的最佳方法
- 如何在成为指向基类的指针后保留对子类方法的使用?
- 从基类实例调用派生类方法而不进行强制转换
- 继承:调用基类的成员和方法
- 通过基类接受方法转发派生 UniquePtr 的右值会移动引用而不是复制
- 引用基类模板的成员变量的简单方法
- C++ 使用派生类方法更改基类数据成员
- C++初始化之前派生类调用基类的方法
- 将派生类方法与基类unique_ptr一起使用
- 为什么派生类的实例从基类调用方法?
- 基类可以声明虚拟方法但不定义它吗?仍然在派生类中定义
- googletest:测试基类具有纯虚拟方法的派生类时的核心转储
- 从基类调用重写的方法
- 为什么允许将派生类的方法static_cast为基类的方法?
- C++-从方法基类调用派生类中的重写方法