在不更改类源代码的情况下,将扩展函数添加到现有类

时间:2014-09-12 06:32:52

标签: c++

我有一个使用旧版开源库的大型C ++应用程序。我想升级到新库。在新的库中,删除了旧函数 fnOldFunction(),并添加了一个新函数 fnNewFunction()。 现在我有两个选择:

  1. 用fnNewFunction()替换fnOldFunction()的所有实例。我有许多其他函数,比如fnOldFunction(),我不想处理具有数千个查找和替换的n个函数。

  2. 我有库的源代码。我可以在那里添加fnOldFunction()并从fnOldFunction()调用fnNewFunction。但即使我有该库的源代码,也不想对libray的源代码进行任何更改。

  3. 任何人都可以给我另一种方法来实现同样的目标。我知道一些语言,如Ruby,Javascript,Objective C提供了扩展/修改现有类的方法,而无需更改该类的源代码。但是C ++缺乏这个功能。

3 个答案:

答案 0 :(得分:2)

一种简单的方法可能是从库类派生自己的类,并重新添加所有旧版本的函数。这不需要编写完整的适配器,也不会触及库代码。您只需要为类名批量重命名,这样不易出错并且可以更好地扩展。

答案 1 :(得分:0)

你可以为这个porpuse使用一个宏。

class A {
public:
  void fnNewFunction() {}
};

int main(void) {
  A a;
  a.fnNewFunction();

#define fnOldFunction fnNewFunction

  a.fnOldFunction();
}

建议使用此技术。这将搞乱intellisense并可能引入错误(如果有另一个同时定义fnOldFunctionfnNewFunction的类会怎样?)

我写这个的原因是因为它回答了你的具体问题。

您的选项1是首选解决方案。您可以轻松使用编辑器的重新分解工具来立即执行此操作。

答案 2 :(得分:0)

我认为这非常适合政策

您可以定义两个接口:

class A {
    void fnOldFunction();
public:
    void fn() {
        fnOldFunction();
    }
};
class B {
    void fnNewFunction();
public:
    void fn() {
        fnFunction();
    }
};

AB可以继承旧/新库的类。 现在,您只需要像这样定义您的工作类:

template <typename Policy>
class C : public Policy {
    /* Whatever you need */
public:
    /* Say doSomething need to call fn */
    void doSomething() {
        /* Whatever */
        fn();
        /* ... */
    }
};

现在,根据您的使用情况,您可以使用C<A>C<B>。请注意,如果库中的许多名称发生了变化,这可能会很麻烦(打破这样的API并不是一个好主意,你有我的同情:()。

使用这个解决方案,与@ Alexander的解决方案几乎完全相同,您仍然可以链接旧库以及新版本。您只需从C<B>切换到C<A>

如果您需要C<A>C<B>,您甚至可以将其与其他元编程技术(如类型特征)相结合,以使编译器推断出来。如果可能的话,你甚至不必触摸代码来编译任何版本的lib。