我使用的第三方库无法控制。它包含2个A和B类,它们都定义了一个具有相同名称的方法:
class A {
public:
...
void my_method ();
};
class B {
public:
...
void my_method ();
};
我想创建一个包含A或B类成员的C类。至关重要的是,我只能在运行时知道是否需要A或B.这个C类只调用方法{{1} }。
如果我可以修改代码,我会简单地使A和B派生自定义my_method的父类(接口)。但我不能。
创建此类C的最简单/最优雅的方法是什么?我当然可以用这种方式定义C:
my_method
但我想避免每次都支付if语句的费用。它也觉得不雅。有没有办法可以创建一个超类型的A或B类?或者这个问题的任何其他解决方案?
答案 0 :(得分:2)
你可以使用std::function
(不确定它有更好的表现),例如:
class C {
public:
void call_my_method() { my_method(); }
void use_a(A* a) { my_method = [=]() { a->my_method() }; }
void use_b(B* b) { my_method = [=]() { b->my_method() }; }
private:
std::function<void()> my_method;
};
答案 1 :(得分:1)
没有;在某些时候你需要分支。您可以做的最好的事情是在调用堆栈†上上/下提升分支,以便将更多的程序封装在比喻if
/ else
构造中分支本身需要不那么频繁地执行。当然,您需要复制更多程序的源代码,这是不理想的。
我此时建议的唯一改进是boost::variant
等构造。它基本上完成了你已经做过的事情,但占用的内存较少,而且没有那个间接层(使用什么称为标记的联合)。它仍然需要分支访问,但直到分析显示这是一个很大的瓶颈(你可能会发现分支预测减轻了大部分风险)我不会进一步了解你的变化。‡
†我永远无法记住它走哪条路lol
‡一个这样的改变可能是有条件地初始化一个函数指针(或现代std::function
),然后每次调用该函数。然而,这是很多间接的。你应该剖析,但我希望它在缓存上变得越来越慢。一个OO纯粹主义者可能会推荐一个多态继承树和虚拟调度,但是一旦你关心这个性能,这对你没有任何用处。
答案 2 :(得分:0)
如何使用虚拟函数继承,使用&#39;基类&#39; (C):
class C
{
public:
virtual void do_method() = 0;
};
class D : public C, private A
{
void do_method() { my_method(); }
};
class E : public C, private B
{
void do_method() { my_method(); }
}
然后这将起作用:
C * d = new D();
d->do_method();
答案 3 :(得分:0)
建议将A和B对象包装成一个帮助模板 TProxy ,它实现了 IProxy 接口。 C类(或消费者)将使用 IProxy 界面,并且不知道代理
内的对象类型#include <stdio.h>
struct A {
void func () { printf("A::func\n"); }
};
struct B {
void func () { printf("B::func\n"); }
};
struct IProxy
{
virtual void doFunc() = 0;
virtual ~IProxy() {};
};
template<typename T>
struct TProxy : public IProxy
{
TProxy(T& i_obj) : m_obj(i_obj) { }
virtual void doFunc() override { m_obj.func(); }
private:
T& m_obj;
};
class Consumer
{
public:
Consumer(IProxy& i_proxy) : m_proxy(i_proxy) {}
void Func() { m_proxy.doFunc();}
private:
IProxy& m_proxy;
};
主要强>
int main()
{
A a;
TProxy<A> aProxy(a);
B b;
TProxy<B> bProxy(b);
Consumer consumerA{aProxy};
consumerA.Func();
Consumer consumerB{bProxy};
consumerB.Func();
return 0;
}
<强>输出:强>
A::func
B::func