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)
和.nowsetData(dataObj)
可以通过继承调用。但对我来说,这根本不是一个选项。如果我们以前必须重写从classFoo
继承的class A的setData(int data)
,这意味着class A需要特殊处理,甚至现在setData(dataObj)
也需要重写,因为它需要特殊处理。因此,这种从base获取默认行为的方法将不起作用。,