C++虚拟方法引发EXC_BAD_ACCESS(仅当Objective-C++调用时)
C++ virtual method raises EXC_BAD_ACCESS (only if called by Objective-C++)
作为一个非常大的代码库的一部分,我有以下内容:
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 changedn";
}
我对C++标准的理解是,这是有效的代码,当doSomething()
运行时,FooObjectChanged()
会被调用两次而不会出现任何错误。
但我的申请在第二次通话时失败了。(带有segfault,或者更准确地说是iOS上的EXC_BAD_ACCESS
)
另一个编译器问题是,如果我删除MainStuff::FooObjectChanged()
(主体及其声明),我会期望链接器失败,并抱怨抽象类。但编译器不会失败。它链接,然后程序在第一次调用的虚拟函数时崩溃
libc++abi.dylib: Pure virtual function called!
发生了什么事?是什么原因导致了这些问题?FooObserver
不是其他任何东西的基类,只是MainStuff
的基类。
- 检查是否有从
MainStuff
中的其他基类继承的任何其他纯虚拟函数,并且您没有在MainStuff
中重写 - Check doSomething是在有效对象上调用的,该对象是活动的并且在作用域内(在调用和处理
MainStuff::doSomething()
时未被销毁)
这是XCode的一些问题。由于某种原因,它停止了重新编译一些源文件。从DerivedData文件夹中删除所有内容并重新启动XCode后,代码将按照预期进行编译、链接和运行。
我只是遇到了类似的问题,我有多个(2个或多个)C++私有类(即class没有Header),所有类都有完全相同的名称,但在不同的.mm
文件中定义了每个都用作std::shared_ptr
智能指针的模板参数(在定义它的同一个.mm
文件中)。
有时,当调用一个类的virtual
方法(使用智能指针的->
运算符)时,Clang
决定使用另一个类vtable
(甚至从未包含其标头),导致二进制文件调用错误的方法地址(以及错误的方法访问的字段,这些字段在类中根本不存在,也称为SIGSEG或BAD_ACCESS)。
我很震惊,因为私有类是一种常见的C++方法,但更改每个私有类的名称(或者至少更改.mm
文件的模板参数中使用的名称)确实解决了Objective-C++(或者更确切地说是Clang)的问题。
- 如何允许模板参数中的类类型,仅当它有两个基类时
- 仅当类型为 std::complex 时,才进行缩放
- 仅当一个参数中未使用 std::function 时,模板函数替换才有效
- 仅当返回表达式有效时才启用模板
- 仅当定义了宏时,C++ else 语句
- 仅当构造函数具有参数时,C++ 公共成员才能访问
- 当(且仅当)对象具有复制构造函数时,如何复制对象?
- 使用 std::cin 的输入仅适用于浮点数,仅当值尾随字母"e"(大写和小写)时
- 仅当ASSERT_STREQ失败时显示差异
- 仅当指针不是 nullptr 时才调用方法
- 仅标头类 + 仅当返回该类的对象时,对函数的未定义引用
- 仅当在客户端部署时,QT 5.9的SSL握手问题
- 仅当元组中存在该类型时,将功能应用于元组元素
- 仅当数据竞赛存在与锁定时,OpenMP关键部分
- C++ 仅当模板参数为 true 时才创建变量
- C++ 仅当模板为字符串类型时执行小写转换
- 仅当链接函数 C++ 时,才会发生"Expression must have class type error"
- 仅当基础类型具有模板类型构造函数时,才实现这些构造函数
- 仅当捕获组最后一次出现时,才使字符成为可选字符
- C++虚拟方法引发EXC_BAD_ACCESS(仅当Objective-C++调用时)