Ete*_*ner 1 c++ pointers class
我刚刚创建了2个具有未定义行为的指针,并尝试调用没有创建对象的类成员函数?
我不明白这个?
#include<iostream>
using namespace std;
class Animal
{
public:
void talk()
{
cout<<"I am an animal"<<endl;
}
};
class Dog : public Animal
{
public:
void talk()
{
cout<<"bark"<<endl;
}
};
int main()
{
Animal * a;
Dog * d;
d->talk();
a->talk();
}
Run Code Online (Sandbox Code Playgroud)
kyo*_*ryu 10
A)这是未定义的行为.任何行为都可能发生.
B)因为你没有调用虚方法,所以很容易解释为什么未定义的行为实际上是这样做的(我在几乎所有我能找到的编译器下测试过这个).
在C++中,调用成员方法与使用隐藏的'this'变量调用成员是等效的(实际上,如果不是在定义中).如果方法是虚拟的,则必须通过vftable,但不能通过非虚方法.
所以
Foo::Bar(){}
Run Code Online (Sandbox Code Playgroud)
是粗略的等价物
Foo_Bar(Foo *this){}
Run Code Online (Sandbox Code Playgroud)
并在调用代码中
Foo *foo = new Foo();
foo->bar();
Run Code Online (Sandbox Code Playgroud)
第二行大致是道德等同于
Foo_Bar(foo);
Run Code Online (Sandbox Code Playgroud)
现在,这里有一些简化,正如我所说,其中一些可能是实现细节而不是规范.但是,行为成立(尽管依赖它是一个错误).
但是,鉴于前面的内容,请看一个实现:
void Foo::Bar(){printf("Hello, world!\n");}
Run Code Online (Sandbox Code Playgroud)
并调用代码:
Foo *foo = 0;
foo->Bar();
Run Code Online (Sandbox Code Playgroud)
正如我们所说,这大致相当于(因为我们是非虚拟的):
Foo *foo = 0;
Foo::Bar(foo);
Run Code Online (Sandbox Code Playgroud)
这意味着我们调用的方法与以下方法相同:
void Foo_Bar(Foo* this)
{ printf("Hello, world\n"); }
Run Code Online (Sandbox Code Playgroud)
现在,给定这个方法,我们实际上并没有消除这个指针!因此,很明显为什么,在这种情况下,该方法将起作用而不会失败.
这样做的实际结果是,在空指针上调用非虚方法,其中方法不解析成员,通常会导致这种观察到的行为.但是,依赖任何未定义的行为基本上都是邪恶的.
当你做一些有不确定行为的事情时,任何事情都可能发生 - 包括它似乎有效.看起来这就是在这种情况下发生的事情.
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |