[英]Grouping two types together
我使用第三方库,我无法控制。 它包含2个A和B类,它们都定义了一个具有相同名称的方法:
class A {
public:
...
void my_method ();
};
class B {
public:
...
void my_method ();
};
我想创建一个包含A或B类成员的C类。至关重要的是,我只能在运行时知道是否需要A或B.这个C类只调用方法my_method
。
如果我可以修改代码,我只需要使A和B派生自定义my_method的父类(接口)。 但我不能。
创建这个C类最简单/最优雅的方法是什么? 我当然可以用这种方式定义C:
class C {
public:
void call_my_method() { if (a) a->my_method() else b->my_method(); }
private:
A* a;
B* b;
但我想避免每次都支付if语句的费用。 它也觉得不雅。 有没有办法可以创建一个超类型的A或B类? 或者这个问题的任何其他解决方案?
您可以使用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;
};
没有; 在某些时候你需要分支。 你可以做的最好的事情就是在调用堆栈中上下调整分支† ,这样你的程序就会被封装在比喻if
/ else
结构中,并且分支本身需要不那么频繁地执行。 当然,您需要复制更多程序的源代码,这并不理想。
我此时建议的唯一改进是诸如boost::variant
类的构造。 它基本上完成了你已经在做的事情,但占用的内存较少,而且没有那个间接层(使用所谓的标记联合 )。 它仍然需要分支访问,但直到分析显示这是一个很大的瓶颈(你可能会发现分支预测减轻了大部分风险)我不会再对你的更改做进一步的了解。 ‡
†我永远不会记得它走哪条路哈哈
‡一个这样的改变可能是有条件地初始化一个函数指针(或现代的std::function
),然后每次调用该函数。 然而,这是很多间接性的。 你应该剖析,但我希望它在缓存上变得越来越慢。 一个OO纯粹主义者可能会推荐一个多态继承树和虚拟调度,但是一旦你关心这个性能,这对你没有任何用处。
如何使用“基类”(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();
建议将你的A和B对象包装成一个实现IProxy接口的帮助模板TProxy 。 C类(或消费者)将使用IProxy接口,并且不知道Proxy内对象的类型
#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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.