- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
考虑以下示例代码:
#include <iostream>
using namespace std;
class base
{
public:
base()
{
bar(); //Line1
this->bar(); //Line2
base *bptr = this;
bptr->bar(); //Line3
((base*)(this))->bar(); //Line4
}
virtual void bar() = 0;
};
class derived: base
{
public:
void bar()
{
cout << "vfunc in derived class\n";
}
};
int main()
{
derived d;
}
上面的代码在基类中有纯虚函数bar()
,它在派生类中被重写了。纯虚函数bar()
在基类中没有定义。
现在关注 Line1
、Line2
、Line3
和 Line4
。
我明白了:第 1 行
给出了编译错误,因为不能从 ctor 调用纯虚函数。
问题:
为什么 Line2
和 Line4
没有编译错误
,原因与我理解
中提到的相同> 上面的声明? Line2
和 Line4
中的调用最终只会导致 linker-error
。
为什么 Line3
既不给出编译错误也不给出链接器错误而只给出运行时异常
?
通过构造函数调用纯虚函数时 UB 的真实示例:
最佳答案
在所有四种情况下,行为都是未定义的;所以究竟会发生什么取决于你的编译器在面对无效输入时碰巧做了什么。
编译器可能会尝试诊断问题并发出警告;这对于第 1 行很容易,而对于其他行则更难,这可以解释为什么您只看到第 1 行的警告。
当从构造函数调用虚函数时,编译器知道应该调用哪个重载,因此它可能会生成静态调用。这就是您从第 2 行和第 4 行收到链接错误的原因。
在第 3 行中,编译器肯定认为确定它是否可以生成静态调用太难了,所以它生成了一个动态调用。跟踪变量的值比确定临时指针必须引用 this
更难,而且通常根本不可能。这就是为什么会出现运行时错误的原因。
当然,所有这些都是未定义的行为,并且可能会因编译器而异,或者根据月相变化。
如果函数有一个实现,那么静态调用它是有效的,如Base::bar()
,或bptr->Base::酒吧()
。动态调用它仍然会产生未定义的行为。
关于c++ - 来自 Base Ctor 的纯虚函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9212212/
我有一个特别的问题想要解决,我不确定是否可行,因为我找不到任何信息或正在完成的示例。基本上,我有: class ParentObject {}; class DerivedObject : publi
在我们的项目中,我们配置了虚 URL,以便用户可以在地址栏中输入虚 URL,这会将他们重定向到原始 URL。 例如: 如果用户输入'http://www.abc.com/partner ',它会将它们
我是一名优秀的程序员,十分优秀!