C++ 虚方法引发 EXC_BAD_ACCESS(仅当由 Objective-C++ 调用时)

Posted

技术标签:

【中文标题】C++ 虚方法引发 EXC_BAD_ACCESS(仅当由 Objective-C++ 调用时)【英文标题】:C++ virtual method raises EXC_BAD_ACCESS (only if called by Objective-C++) 【发布时间】:2014-12-23 09:08:44 【问题描述】:

作为一个非常大的代码库的一部分,我有以下内容:

class FooObserver 
public:
     virtual void FooObjectChanged() = 0;
;

class MainStuff :  public FooObserver 
public:
    /* ... */
    void FooObjectChanged();
    void doSomething();
;

void MainStuff::doSomething()     
    this->FooObjectChanged();
    FooObserver *o = this;
    o->FooObjectChanged();


void MainStuff::FooObjectChanged() 
    std::cout << "object changed\n";

我对 C++ 标准的理解是,这是有效代码,FooObjectChanged() 会在 doSomething() 运行时被调用两次而不会出现任何错误。

但是我的应用程序在第二次调用时失败了。 (带有段错误,或者更准确地说是 ios 上的 EXC_BAD_ACCESS

另一个编译器问题是,如果我删除 MainStuff::FooObjectChanged()(主体及其声明),我希望链接器会因抱怨抽象类而失败。但编译器不会失败。它链接,然后程序在第一次调用虚函数时崩溃

libc++abi.dylib: Pure virtual function called!

发生了什么事?什么可能导致这些问题? FooObserver 不是其他任何东西的基类,只是 MainStuff 的基类。

【问题讨论】:

构造函数不能是纯虚函数!而且也不应该是虚函数! 你是说构造函数?这在 C++ 中甚至不能是虚拟的,所以它们都不在这个应用程序中。 您是直接还是间接地将其 from 称为构造函数?另外,make clean 看看它是否一直在崩溃。 它不是从构造函数中调用的。但是“make clean”似乎是在正确的方向,我仍在努力确保,但似乎 XCode 搞砸了构建。 【参考方案1】:

我刚遇到类似的问题,我有多个(2 个或更多)C++ private-Classes(即 Class 没有 Header),并且都具有完全相同的名称,但 已定义 在不同的.mm 文件中; 每个都用作模板参数(在同一个 .mm 文件中,在其中定义)std::shared_ptr 智能指针。

有时在调用一个类的virtual 方法(使用智能指针的-&gt; 运算符)时,Clang 决定使用另一个类的vtable(甚至从未包括标题) ,导致二进制调用错误的方法地址(以及错误方法访问的字段,这些字段根本不存在于类中,即 SIGSEG 或 BAD_ACCESS)。

我很震惊,因为私有类是一种常见的 C++ 方法,但是更改每个私有类的名称(或至少,在 .mm 文件的模板参数中使用的名称),确实修复了 Objective-C++ 的(或者更确切地说是 Clang 的)问题。

【讨论】:

【参考方案2】:

这原来是 XCode 的一些问题。由于某种原因,它停止重新编译一些源文件。从 DerivedData 文件夹中删除所有内容并重新启动 XCode 后,代码将按我的预期编译、链接和运行。

【讨论】:

【参考方案3】:
    检查MainStuff中是否有任何其他纯虚函数继承自其他基类,并且您没有在MainStuff中覆盖 检查 doSomething 是否在有效且在范围内的有效对象上调用(在调用并处理 MainStuff::doSomething() 时未销毁)

【讨论】:

所有其他纯虚函数在 MainStuff 中都被覆盖了,我在使用它们时没有发现任何问题。 MainStuff 是活跃的并且在范围内。 @pramparam 然后尝试重新编译整个代码,应该没问题,从您发布的代码 sn-p 看不出任何问题 #1 甚至没有意义;如果没有实现/定义单个“纯虚函数”(例如:无法构造抽象类),任何理智的编译器都会引发编译错误。

以上是关于C++ 虚方法引发 EXC_BAD_ACCESS(仅当由 Objective-C++ 调用时)的主要内容,如果未能解决你的问题,请参考以下文章

[ C++ ] 抽象类 虚函数 虚函数表 -- C++多态

C++:多态公有继承中的虚方法

什么是C++虚函数虚函数的作用和使用方法

C++ 虚函数 (virtual function)

C++在多态子类中添加虚方法

C++ 纯虚函数 虚函数 override