具有显式派生方法的C++接口
C++ Interface With Explicit Derived Methods
我有一个示例接口,它将行为委托给实现类:
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*在其中一个重载中被接受。
其次,在每个实现者都有一个接受接口的共享方法的情况下,如何实现接口方案?也许只使用免费方法并从IBase接口中删除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错误C2665:"anonymous-namespace'::method' : none of the 2 overloads could convert all the argument types
Error 2 error C2665: '
匿名命名空间"::方法":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++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- Visual C++GC接口如何启用它以及要包含哪个库
- Windows.h与GLFW.h的接口
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 提供与TMP和SFINAE的通用接口
- 为重写std::exception的库生成swig接口时出错
- 内联如何影响模块接口中的成员函数
- COM 接口 c# 封送数组数组
- 如何在 SCIP C++ 接口中获取 MILP 约束矩阵中的系数值
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如何绑定 C++ gRPC 客户端的网络接口
- 模板化接口 - 创建一个泛型模板类以返回任何容器
- 如何从实现接口的模板化类实例访问结构
- 带有进度表的 curl 多接口程序
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 我可以在具有一个标头和一个接口的 cpp 文件中有多个嵌入吗?
- 类接口,可以创建N个方法
- 类具有相同的接口,但参数的类型不同
- 如何与 Cheerp/js 中的 extern 变量接口?
- 如何使用现代 CMake 安装捆绑的接口依赖项?