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

C++ C++;在运行时检查函数签名是否存在?,c++,rtti,C++,Rtti,目前的情况是:我正在进行一些代码重新分解 如果你看这张图片,目前的情况是我有一个虚拟方法setData(intid) 现在我们想将其更改为虚拟方法setData(dataObj aObj) 但是这样做是一个漫长的过程,因为我们的foo对象被大量类继承。因此,我们希望逐渐改变代码 因此,我需要做的是检查继承的类中是否有一个已经实现 setData(dataObj aObj)调用该类,否则调用前面的另一个函数签名 setData(int-ID)问题进一步复杂化,因为,FOO类以前提供了默认的set

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

如果你看这张图片,目前的情况是我有一个虚拟方法
setData(intid)
现在我们想将其更改为虚拟方法
setData(dataObj aObj)

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

因此,我需要做的是检查继承的类中是否有一个已经实现
setData(dataObj aObj)
调用该类,否则调用前面的另一个函数签名
setData(int-ID)
问题进一步复杂化,因为,
FOO
类以前提供了默认的
setData(int-ID)
,并且并非所有继承自
FOO
的类都可能/可能不需要实现
setData
,它们的实现差别很大

我已经看过了 不幸的是,这并没有回答我的问题

在我看到的一些帖子中,人们使用模板,这对我来说不是一个选项,因为这需要在运行时完成。其他选项似乎建议使用GCC等链接/破坏技巧。我需要构建独立于平台和编译器的代码。所以这也不是一个选择

如果有更多的建议,唯一可能的解决办法似乎是
但我真的不知道如何在我的工作流程中实现这一点,或者这是否与我的问题有关

您可以执行以下操作:

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; }

和适当<代码>无效SETATDATA(DATAObjAOBJ)< /C> > /P> < P>如果修改DATAOBJ类是一个选项,创建和销毁DATAOBO对象不太昂贵,那么您可以考虑以下内容。我不是特别喜欢它,但就短期黑客而言,我看到了更糟的

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;
}
classdataobj
{
int x;
公众:
int getID(void)常量{

std::难道你不能。相反,修复你过于复杂的设计(这很有趣;你自己也提到过:“问题因为……而变得更复杂了”)。出于好奇:为什么在运行时会发生这种情况?我看到的是mspaint恐怖吗?为了您自己的理智,请查看此类图表。最起码,在您意识到最终图像中的文本太小后,您几乎可以立即调整它们的大小。此外,为了确保您没有体验到这种情况,请提供一点信息关于你实际上想做什么以及为什么选择这个特殊的(不可能的)细节解决方案。在
Init
方法中,
ID
aObj
来自哪里?我不是设计模式方面的专家。但是有没有一些设计模式、委托、函子方法可以让我更优雅地完成这项工作,或者不涉及派生类?从我所看到的开始,这很可能不是不可能。@Jarod42,如果没有其他问题,我可能会接受这个答案。这似乎是在派生类部分实现最低增量代码更改量的唯一选项,以完成我的尝试。@thassan:如果您已经有了访问者,您可以使用它。否则您可以使用
if
dynamic\u cast级联对于每个派生类,但它不那么优雅,但不涉及层次结构。谢谢,但这不完全是我的情况。如果我看一下你的建议,你的类A现在也继承了
setData(dataObj)
以前它用来覆盖
setData(int-ID)
和.now
setData(dataObj)
可以通过继承调用。但对我来说,这根本不是一个选项。如果我们以前必须重写从class
Foo
继承的class A的
setData(int data)
,这意味着class A需要特殊处理,甚至现在
setData(dataObj)
也需要重写,因为它需要特殊处理。因此,这种从base获取默认行为的方法将不起作用。,