Code Bye

这段代码有什么问题

struct base {
virtual void foo() {};
};
struct derived : public base {
void foo() { base:foo(); }
};
int main() {
base* b = new derived();
b->foo();

delete b;
}
问题大致知道出在哪儿,但是base:foo()是什么用法啊?

解决方案

20

引用:
Quote: 引用:
Quote: 引用:
Quote: 引用:

学过构造函数吗?一个子类被构造时,先调用父类的构造函数,然后再调用子类的构造函数。
这个过程是编译器帮你实现的。
那么,你这段代码,其实是相似的原理的,在foo的逻辑之前,先调用父类的foo。
它的意义和调用父构造函数是一样的。

base:foo()编译没错,运行会出错
base::foo()运行正常

汗,原来你问的是这个….
base:foo() 这个是语法错误…………..你见过有函数调用是这样写的吗?

引用:
Quote: 引用:
Quote: 引用:

学过构造函数吗?一个子类被构造时,先调用父类的构造函数,然后再调用子类的构造函数。
这个过程是编译器帮你实现的。
那么,你这段代码,其实是相似的原理的,在foo的逻辑之前,先调用父类的foo。
它的意义和调用父构造函数是一样的。

base:foo()编译没错,运行会出错
base::foo()运行正常

汗,原来你问的是这个….
base:foo() 这个是语法错误…………..你见过有函数调用是这样写的吗?

你可以去编译器上试试,编译没有问题的

struct derived : public base {
	void foo() {

		printf("--\n");
	base:foo();

	}
};

找到原因了,这是一个递归掉用,报的错是栈溢出
base:foo(); 这个语法等价到this.foo();
base::foo()是直接call 父类的foo()
base:foo() 将会以this为参数,通过虚表查找到 foo再call

base:foo();
0111154A  mov         eax,dword ptr [this]  
0111154D  mov         edx,dword ptr [eax]  
0111154F  mov         esi,esp  
01111551  mov         ecx,dword ptr [this]  
01111554  mov         eax,dword ptr [edx]  
01111556  call        eax   //这个是是计算后的偏移地址
01111558  cmp         esi,esp  
0111155A  call        __RTC_CheckEsp (01111163h)  
	base::foo();
0111155F  mov         ecx,dword ptr [this]  
01111562  call        base::foo (01111050h)

//直接是 父类的函数地址入口


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明这段代码有什么问题