C ++在运行时检查函数签名是否存在?

时间:2013-12-26 23:37:23

标签: c++ rtti

目前的情况是:我正在通过一些代码重新分解

enter image description here

如果你看图像,目前的情况是我有一个虚拟方法setData(int ID); 现在我们要将其更改为虚拟方法setData(dataObj aObj);

但这样做是一个漫长的过程,因为我们的foo对象已被大量的类继承。所以,我们希望逐步改变代码。

因此,我需要做的是检查其中一个继承类是否已实现 setData(dataObj aObj)调用该类,否则调用其他先前的函数签名 setData(int ID);问题进一步复杂化的事实是,FOO类之前提供了默认的setData(int ID),而不是所有从FOO继承的类因此可能/可能不需要实现setData及其实施方式确实存在很大差异。

我已经看过了 How to Check if the function exists in C/C++ 不幸的是,这不回答我的问题。

在我看过人们使用模板的一些帖子中,这对我来说不是一个选项,因为这需要在运行时完成。其他选项似乎建议将链接/修改技巧与GCC等联系起来。我需要构建我的代码以使其与平台和编译器无关。所以这也不是一个选择。

任何更多建议,唯一可能的近似解决方案似乎是 https://stackoverflow.com/a/8814800/1376317 但我真的不确定如何在我的工作流程中实现这一点,或者这是否与我的问题相关。

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

class Foo
{
public:
    // Old interface
    virtual void setData(int ID) { /* Old default implementation */ }

    // New interface
    virtual void setData(dataObj aObj) { /* New default implementation */ }

    void init() {
        if (useOldInterface()) {
            setData(ID);
        } else {
            setData(aObj);
        }
    }

private:
    // temporary method to be removed once all derived classes return false.
    virtual bool useOldInterface() const { return true; }
};

通过添加

来逐步更改派生类
virtual bool useOldInterface() const override { return false; }

并且恰当void setData(dataObj aObj)

答案 1 :(得分:1)

如果修改dataObj类是一个选项,并且创建和销毁dataObj对象不是太贵,那么可以考虑以下内容。我不是特别喜欢它,但就短期黑客而言,我已经看到更糟了......

class dataObj
{
int x;
public:
    int getID(void) const { 
        std::cout << "dataObj::getID " << std::endl;
        return x;
    }
    dataObj() : x(0){}
    ~dataObj(){}

};
class Foo
{
public:
    // Old interface
    virtual void setData(int ID) {
        /* Old default implementation */
        std::cout << "Foo::setData int" << std::endl;
    }

    // New interface
    virtual void setData(const dataObj& aObj) {
        /* New default implementation */
        std::cout << "Foo::setData dataObj" << std::endl;
        setData(aObj.getID());
    }

};

class A : public Foo
{
public:
    virtual void setData(int ID) {
        /* Old default implementation */
        std::cout << "A:: setData int" << std::endl;
    }

};

class B : public Foo
{
public:
    virtual void setData(const dataObj& aObj) {
        /* Old default implementation */
        std::cout << "B:: setData dataObj" << std::endl;
    }

};

int main(int argc, char* argv[])
{
    A a;
    B b;
    dataObj d;
    Foo* pa, * pb;
    pa = &a;
    pb = &b;
    pa->setData(d);
    pb->setData(d);
return 0;
}