C++多态求指导

C++语言 码拜 9年前 (2016-04-21) 1103次浏览
博客看到http://blog.csdn.net/hackbuteer1/article/details/7475622借用博主文章的内容,再此谢过。
#include<iostream>
using namespace std;
class A
{
public:
void foo()
{
printf(“1\n”);
}
virtual void fun()
{
printf(“2\n”);
}
};
class B : public A
{
public:
void foo()
{
printf(“3\n”);
}
void fun()
{
printf(“4\n”);
}
};
int main(void)
{
A a;
B b;
A *p = &a;
p->foo();
p->fun();
p = &b;
p->foo();
p->fun();
return 0;
}
笔试的题目中还有一个另类测试方法。即
B *ptr = (B *)&a;  ptr->foo();  ptr->fun();
问这两调用的输出结果。这是一个用子类的指针去指向一个强制转换为子类地址的基类对象。结果,这两句调用的输出结果是3,2。
并不是很理解这种用法,从原理上来解释,由于B是子类指针,虽然被赋予了基类对象地址,但是ptr->foo()在调用的时候,由于地址偏移量固定,偏移量是子类对象的偏移量,于是即使在指向了一个基类对象的情况下,还是调用到了子类的函数,虽然可能从始到终都没有子类对象的实例化出现。
而ptr->fun()的调用,可能还是原因是C++多态性的原因,由于指向的是一个基类对象,通过虚函数列表的引用,找到了基类中fun()函数的地址,因此调用了基类的函数。由此可见多态性的强大,可以适应各种变化,不论指针是基类的还是子类的,都能找到正确的实现方法。
博客上如此解释,但是本人还是不清楚,有哪位高手能再次详解么,谢啦
解决方案

5

这样想吧:foo()是非虚函数,所以申明的是什么类,调用的就是哪个类的foo
fun()是虚函数,所以不管申明的是什么类,调用的时候都是按照实际是什么类的fun执行
不过话说回来,也不要太纠结于这些,原因是实际代码中总会要求虚函数一定要加上virtual ,class B里面的fun这种前面不加visual的,简直就是混淆视听,拙劣的设计,一巴掌拍死

5

没有virtual修饰,什么类声明,就是哪个的实现
有virtual修饰,什么类构造,就是哪个的实现

5

感觉那篇博客没说出原理,网上给你搜了篇
http://blog.csdn.net/justaipanda/article/details/8137435
假如lz刚开始学的话,不太建议一开始研究太深。

5

#include <iostream>
#include <new>
using namespace std ;
struct A {
	int a ;
	virtual void set () = 0 ;
} ;
struct B :public A {
	void set () override { a = 12 ; }
} ;
void set (A &l) { l.a = 24 ; }
int main () {
	char tmp[sizeof (A)] = {0} ;
	A &p = reinterpret_cast<A &> (tmp) ;
	void *const *&vptr = reinterpret_cast<void *const *&> (p) ;
	p.a = 6 ;
	cout << p.a << " " << vptr << endl ;
	new (&p) B () ;
	p.set () ;
	cout << p.a << " " << vptr << endl ;
	void (*const vptr0) (A &) = (void (*) (A &)) vptr[0] ;
	void *const nvptr[] = {set} ;
	vptr = nvptr ;
	p.set () ;
	cout << p.a << " " << vptr << endl ;
	vptr0 (p) ;
	cout << p.a << " " << vptr << endl ;
	return 0 ;
}

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C++多态求指导
喜欢 (0)
[1034331897@qq.com]
分享 (0)