繁体   English   中英

将两种类型组合在一起

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM