gpt4 book ai didi

c++ - 为虚拟析构函数指定的冲突类型属性

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:19:36 25 4
gpt4 key购买 nike

以下摘录之前是在 Borland C++、MSVC 和 OpenWatcom 下编译的:

class aaa {
virtual _fastcall ~aaa();
};

class bbb:public aaa {
};

它不能在 gcc/g++ (MinGW 4.8.0) 下编译。错误:

probz.cpp:7:7: error: conflicting type attributes specified for 'virtual bbb::~bbb()' class bbb:public aaa {       ^probz.cpp:3:20: error:   overriding 'virtual aaa::~aaa()'   virtual _fastcall ~aaa()=0;///can't be abstract                     ^

显然,没有 bbb::~bbb()!

编辑

实际的类层次结构更大,有很多bbb类继承自aaa,中间还有一些中间成员,即bbb extends abb,它extends aab,延伸 aaa。 aaa 确实有一个抽象的虚拟析构函数,它在中间类中得到实现,但在叶子中没有。是的,我可以删除 __fastcall 属性并进行编译。我不能调整调用约定是 gcc 的限制吗?

最佳答案

__fastcall是一个调用约定。

这是一个非标准功能:名称开头的双下划线表示它是特定于实现。调用约定与系统和 CPU 架构密切相关。这似乎与 x86 32 位模式有关。

一些建议:

  • 除非绝对需要(例如,当与预编译库或 extern dlls 交互时),否则您不应该为调用约定而烦恼。
  • 现代编译器执行的优化级别不再需要此类手动调整。这同样适用于关键字 register
  • 如果您的代码在某些平台上确实需要它,您应该在其中一个 header 中预见到 #define 并确保通过条件编译它在不相关的平台/编译器上没有定义(对于 DLL,这种方法很常见,使用特定于库的 #define)。
  • 所有派生类的调用约定应该相同,因此最好在基类中声明。对于虚函数,这是一个隐含的强制要求!想象一下,您的基类通过堆栈传递参数,派生类通过寄存器传递参数(fastcall)。现在,如果您通过基类指针进行多态调用,您的编译器应该生成什么代码?如果两个派生类使用不同的调用约定会怎样?
  • 您不能假设调用约定是自动继承的:标准在此处不做任何保证
  • 如果您必须指定调用约定,请尽可能首选外部链接说明符(例如 extern "C" ),因为这是唯一与调用约定相关的语义受标准支持。

附加信息:

关于c++ - 为虚拟析构函数指定的冲突类型属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28385849/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com