如果函数是从抽象类派生的,则不能用具体的类指针调用该函数
Not able to call function with concrete class pointer, if it is derived from abstract class
我正在使用"g++(Ubuntu/Linaro 4.6.3-1ubuntu5(4.6.3"来运行我的代码。两者都是经过编译的程序。
(1.(
以下程序运行时存在分段故障
#include <iostream>
using namespace std;
class Abstract {
public:
virtual void func() = 0;
};
class A : public Abstract {
public:
void func() { cout << "func()" << endl; }
};
int main() {
A *ao;
ao->func(); //--> Segmentation fault`<br/>
/*
if we do
A *ao = new A;
ao->func();
then its working
*/
return 0;
}
当A现在是定义Abstracts方法的具体类时,为什么会观察到这种行为?
(2(如果类不是从抽象类派生的,那么它在这里是有效的。
class A {
public:
void func() { cout << "func()" << endl; }
};
int main() {
A *ao;
ao->func();
return 0;
}
使用时,
A *ao;
ao->func(); //--> Segmentation fault
ao
未初始化为指向有效对象。在这样的指针上调用成员函数会导致未定义的行为。在您的情况下,这表现为分段错误。
事实上,当没有抽象基类时,它会起作用,这是未定义行为的意外后果,在这种情况下,似乎是理智的行为。
在实际操作中,看似正常的行为是因为您在调用中没有使用A
的任何成员变量。在抽象基类的情况下,使用虚拟表。由于指针未初始化为指向有效对象,因此尝试访问虚拟表会导致分段错误。
您有未定义的行为,因为您使用的是未初始化的指针,就好像它被分配了有效对象的地址一样。编译器不会帮你检查——这取决于你把它指向合理的地方。
你所做的有点像把一封信丢在邮箱里,上面没有写地址——谁知道会发生什么?
第一个程序可能会出现分段错误,但第二个程序不会出现,但C++标准并不能保证每次运行程序时都会出现这种错误,更不用说重新编译程序、更改编译器参数、修改代码、尝试其他编译器等了
在实践中,当函数不是虚拟的时,你碰巧"逃脱"它的原因可能是被调用的函数func
没有试图通过传递给它的伪this
指针访问任何对象数据(它将接受ao
的值(:所以指针是垃圾也没关系。当函数为virtual
时,它会尝试使用this
指针来查找指向虚拟调度表的指针,但随后垃圾指针实际上被卡住,程序崩溃。如上所述,这两种行为都没有得到保证-它是未定义的。
A *ao;
ao->func(); //--> Segmentation fault
ao会有一些垃圾值,当你尝试ao->func((时,你正试图访问ao指向的内存,因为很可能你没有访问权限,所以会出现内存分段错误
A *ao = new A;
ao->func();
then its working
新操作符将为A的实例分配内存,并返回到ao的有效指针,因此它将正常工作。
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针