gpt4 book ai didi

c++ - 需要覆盖逆变变通方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:11:35 24 4
gpt4 key购买 nike

我很难找到(我确信这是一种非常常见的)设计模式来解决以下问题。考虑这段代码:

class AA {};
class BB : public AA {};

class A
{
public:
virtual void foo(AA& aa) = 0;
};

class B : A
{
public:
void foo(BB& bb){cout<<"B::foo"<<endl;}
};

int main()
{
B b;
BB bb;
b.foo(bb);
}

这段代码不会编译,因为类 B 没有覆盖纯虚函数“foo”。编译器仅将 B 声明的 foo 视为对 foo 的重载,因为重写函数的输入参数中不允许协变。

现在,我明白了其中的原因。 B 继承自 A 的事实意味着它应该能够处理任何带有 AA 类型参数的 foo 调用,而之前的代码没有给出处理除 BB 之外的任何参数类型的实现。

当然,我可以在 B 的 foo 实现中将 aa 转换为 BB,但我正在寻找一种保留类型安全的解决方案,并且实际上强制 B 类的实现者也按顺序实现从 AA 继承的类用于编译代码。在理想情况下,我将能够编写类似于以下伪代码的内容:

class A
{
public:
abstract class AA{}; //indicates that any child of A must implement also child of AA
abstract void foo(AA& aa);
};

class B : public A
{
public:
class BB : AA{}; //will not compile without this
void foo(BB& bb){cout<<"B::foo"<<endl;}
};

有没有办法在 C++ 中实现类似的功能? (也许可以通过某种不需要继承的映射对象来提升)

请注意,实际上(与示例中不同),BB 和 AA 之间的继承是至关重要的,因为 AA 有许多 child 具有许多共同的品质,最后我想要完成的是迭代 A 类的 vector 并仅使用适当的参数(AA 的 vector )运行“foo”

最佳答案

要提供类型安全,您应该使用模板而不是继承。

class AA {};
class BB : AA {};

template <typename Managed> class FooManager {
virtual void foo(Managed& m) { /* default implementation */ }
};

class B : public FooManager<BB> {
void foo(BB bb) { cout << "B:foo()" << endl; }
};

后面的代码,比如要遍历一个数组,

template<typename Managed> void processAll(vector<Managed> v, FooManager<Managed> mgr) {
for(Managed& m : v) mgr.foo(m);
}

B b;
vector<BB> bbs;
processAll(bbs, b);

编辑:拼写错误修复

关于c++ - 需要覆盖逆变变通方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7144893/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com