我理解以下代码不起作用 - 无法将base转换为foo。
我能做些什么,或者采用哪种模式让我接近我在下面的代码中尝试实现的行为? IOW,如果我有一个指向派生类型的基类指针,我该如何调用与派生类型匹配的特定方法(而不是基类型)?
我可以使用哪些模式?我查看了Curiously Recursive(或重复)模板模式,但是这本身也带来了其他限制。
class base {};
class foo : public base {};
void method(const foo& f){}
int main(){
base* b = new foo();
method(*b);
}
答案 0 :(得分:2)
最简单的方法可能是在method()
上virtual
成为foo
成员函数:
class base {
public:
virtual void method() const = 0;
};
class foo : public base {
public:
void method() const override { }
};
int main(){
foo f;
base* b = &f;
b->method();
}
但如果由于某种原因无法实现(也许您无法访问method()
或者您希望将method()
中的逻辑与foo
分开您可以使用Visitor Pattern的简化版本。
访问者模式依赖于层次结构中具有基于类类型分派的虚函数的所有类。
在您的情况下,您不需要双重发送,因此您实际上并不需要访问者对象,只能直接从虚拟method
函数调用dispatch
函数:
class base {
public:
virtual void dispatch() const = 0;
};
class foo : public base {
public:
void dispatch() const override;
};
void method(const foo& f){}
void foo::dispatch() const {
method(*this);
}
int main(){
foo f;
base* b = &f;
b->dispatch();
}
您必须记住,在大多数情况下,编译器并不知道您的base
指针实际上是foo
类型。
答案 1 :(得分:1)
使用virtual
函数来解决这些问题:
class base {
public:
virtual void func() const { /* A */ }
};
class foo : public base {
public:
void func() const override { /* B */ }
};
void method(const base& f) {
f.func();
}
int main(){
base* b = new foo();
method(*b);
}
现在,根据f
的实际类型,A
或B
代码将在method
中执行。