gpt4 book ai didi

具有显式派生方法的 C++ 接口(interface)

转载 作者:行者123 更新时间:2023-11-28 06:23:51 24 4
gpt4 key购买 nike

我有一个将行为委托(delegate)给实现类的示例接口(interface):

class IBase
{
public:
virtual void Do(IBase* base) = 0;
virtual std::string name() = 0;
};

然后我有 1..N 个实现 IBase 的类:

class A : public IBase
{
public:
virtual void Do(IBase* base);
virtual std::string name() { return "A"; }
};

class B : public IBase
{
public:
virtual void Do(IBase* base);
virtual std::string name() { return "B"; }
};

然后我希望 Do() 方法的主体调用为实现 IBase 的所有内容定义的自由方法:

void method(A* a, B* b)
{
std::cout << a->name() << " " << b->name() << std::endl;
}

void method(B* b, A* a)
{
method(b, a);
}

这不会编译,因为使用此代码,因为 IBase 无法解析为派生类型:

void Test::Run()
{
IBase* a = new A();
IBase* b = new B();

b->Do(a);
}

我如何使这项工作或类似的工作?免费方法实现了所有可能的组合,似乎有一个技巧可以让 IBase* 在其中一个重载中被接受。

其次,如何实现一个接口(interface)方案,其中每个实现者都有一个采用接口(interface)的共享方法?也许仅使用免费方法并从 IBase 接口(interface)中删除 Do(IBase*) 可以更好地实现这一点。

编辑:如果 (a) 被声明为 A 类型,它就可以工作。使上面的代码与 IBase 一起工作的最佳方法是什么?

void Test::Run()
{
A* a = new A();
IBase* b = new B();

b->Do(a);
}

我正在编译的文字代码:

class IBase
{
public:
virtual void Do(IBase* base) = 0;
virtual std::string name() = 0;
};

class A : public IBase
{
public:
virtual void Do(IBase* base);
virtual std::string name();
};

class B : public IBase
{
public:
virtual void Do(IBase* base);
virtual std::string name();
};

class Test
{
public:
static void Run();
};

namespace
{
void method(A* a, B* b)
{
std::cout << a->name() << " " << b->name() << std::endl;
}

void method(B* b, A* a)
{
method(b, a);
}
}

void A::Do(IBase* base)
{
method(this, base);
}

std::string A::name()
{
return "A";
}

void B::Do(IBase* base)
{
method(this, base);
}

std::string B::name()
{
return "B";
}

void Test::Run()
{
IBase* a = new A();
IBase* b = new B();

b->Do(a);
}

Visual Studio 2013:

错误 1 ​​error C2665: 'anonymous-namespace'::method' : 2 个重载中没有一个可以转换所有参数类型
错误 2 error C2665: '
anonymous-namespace'::method' : 2 个重载中没有一个可以转换所有参数类型

最佳答案

所以如果我理解正确的话,你希望 A::Do 看起来像这样:

void A::Do(IBase* other) {
if other is A, then call:
method(this,other) for arguments A,A
else if other is B, then call
method(this,other) for arguments A,B
etc.
}

对此有两个答案。最好的方法通常是更改设计。使方法成为 IBase 中的虚函数而不是自由函数,并将特定于 A 和 B 的任何功能提取到另一个虚函数中。

class IBase
{
public:
virtual void Do(IBase* base) = 0;
virtual std::string name() = 0;
virtual void method(IBase* other);
virtual void method2() = 0;
};

void IBase::method(IBase* other) {
std::cout << name() << " " << other->method2() << std::endl;
}

另一种选择是使用类型转换:

void A::Do(IBase* other) {
if other is A, then call:
method(this,dynamic_cast<A*>(other)))
else if other is B, then call
method(this,dynamic_cast<B*>(other))
etc.
}

这种方法通常不能很好地扩展,难以维护且容易出错。

关于具有显式派生方法的 C++ 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28869742/

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