将两种类型组合在一起

时间:2016-07-07 11:59:45

标签: c++ c++11 gcc

我使用的第三方库无法控制。它包含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类?或者这个问题的任何其他解决方案?

4 个答案:

答案 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