大家分析一下这段代码

liumingrong 2007-11-22 10:40:40
#include <iostream>
using namespace std;


class A
{
public:
A():a(1)
{}
virtual void print()
{
cout << "A print\n";
cout << a << endl;
}
virtual void test()
{
print();
}
private:
int a;
};

class B:public A
{
public:
B():a(2)
{}
virtual void print()
{
cout << "B print\n";
cout << a << endl;
}

virtual void test()
{
print();
A::test();
A::print();
}
private:
int a;
};
int main()
{
B b;
b.test();
}
...全文
159 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
liumingrong 2007-11-24
  • 打赏
  • 举报
回复
在64位机器上写了个测试程序,确实编译器对this作了手脚
#include <iostream>

using namespace std;

class A
{
public:
A():a(1){}
virtual void print()
{
cout << "this in A: " << this << endl;
cout << "typedid test(A?): " << (typeid(*this) == typeid(A) ) << endl;
cout << "this->a : " << this->a << " " << &(this->a) << endl;
print();
}
int a;
int b;
int c;
};

class B
{
public:
B():a(2){}
virtual void print()
{
cout << "this in B: " << this << endl;
cout << "typeid test(B?): " << (typeid(*this) == typeid(B) )<< endl;;
cout << "this->a : " << this->a << " " << &(this->a) << endl;
print();
}
int a;
};

class C:public A,public B
{
public:
C():a(3)
{
}
void test()
{
cout << "this in C: " << this << endl;
cout << "typeid test(C?): " << (typeid(*this) == typeid(C) )<< endl;;
A::print();
B::print();
}
void print()
{
cout << a << "=>" << &(a) << endl;
}

int a;
int b;
};

int main(int argc,char** argv)
{
C c;
c.test();
cout << "\n***************************************\n";
A a;
cout << "A : size" << sizeof(A) << "[" << &a << "] "
<< a.a << "=>" << &a.a << " " << a.b << "=>" << &a.b << " " << a.c << "=>" << &a.c << endl;
B b;
cout << "B : size" << sizeof(B) << "[" << &b <<"]"
<< b.a << "=>" << &b.a << endl;

cout << "C: size" << sizeof(C) << "[" << &c << "] "
<< &c.A::a << " " << &c.A::b << " " << &c.A::c << endl
<< &c.B::a << endl
<< &c.a << " " << &c.b <<endl;

printf("A offset:%p,%p,%p\n",&A::a,&A::b,&A::c);
printf("C offset:%p,%p\n",&C::a,&C::b);
}

this in C: 0x7fbffff8b0
typeid test(C?): 1
this in A: 0x7fbffff8b0
typedid test(A?): 0
this->a : 1 0x7fbffff8b8
3=>0x7fbffff8d4
this in B: 0x7fbffff8c8
typeid test(B?): 0
this->a : 2 0x7fbffff8d0
3=>0x7fbffff8d4

***************************************
A : size24[0x7fbffff890] 1=>0x7fbffff898 127=>0x7fbffff89c 5249296=>0x7fbffff8a0
B : size16[0x7fbffff880] 2=>0x7fbffff888
C : size48[0x7fbffff8b0] 0x7fbffff8b8 0x7fbffff8bc 0x7fbffff8c0
0x7fbffff8d0
0x7fbffff8d4 0x7fbffff8d8
A offset:0x8,0xc,0x10
C offset:0x24,0x28

qhfu 2007-11-23
  • 打赏
  • 举报
回复
应该定义一个virtual 析构函数 给A
星光伴月 2007-11-23
  • 打赏
  • 举报
回复
真的等于没说吗?多态是怎么实现的?不就是用虚函数吗?
aipb_1 2007-11-22
  • 打赏
  • 举报
回复
实际上?

楼上说了等于没说!
星光伴月 2007-11-22
  • 打赏
  • 举报
回复
结果:
B print
2
B Print
2
A Print
1
分析:
class A 与 class B的Test函数和Print函数都是虚函数,而B继承了A,它们的成员变量a互不影响,在B中,如果访问A的成员变量a时,必须显式访问:
A::a
main函数中,只声明了一个B的变量b,并调用了b.test();
b::test中,首先调用自己的print函数,print函数输出a是自己的成员变量,而不是其父类A的,所以第一次输出2
紧接着调用A::test,在test中的print()相当于this->print(),也就是用指针调用A的print,而A的print是虚函数,所以实际上将运行B::print,因此,第二次也输出2
最后调用A::print,这个print确实是调用的A自己的print,所以输出1;
rhwfyf 2007-11-22
  • 打赏
  • 举报
回复
B b;

首先调用A的构造函数,将A的私有数据成员 int a 设置为1;
然后调用B的构造函数,将B的私有数据成员 int a 设置为2;
注意这两个a是不同的,因为是私有数据成员,所以不继承.


b.test();
首先调用b.print(),输出B print 2;
对于A::test(),实际上调用的是B的print(),因为print()是虚函数,实际调用对象是B类的b对象,
输出B print 2
最后A::print()输出A print 1
aipb_1 2007-11-22
  • 打赏
  • 举报
回复
能结合代码里那两次调用分析下不?
看不太明白!
liumingrong 2007-11-22
  • 打赏
  • 举报
回复
谢谢
我是想知道在使用A::xx()调用时,编译器是不是将this指针作了调整,否则在cout < < a < < endl; 中输出就为2了
飞哥 2007-11-22
  • 打赏
  • 举报
回复
我给你抄书一段:

系统需要首先定位这个指针或者引用真正对应的对象,所隐含的虚函数指针。
然后根据这个虚函数的名称,对这个虚函数指针所指向的虚函数表进行一个偏移定位,再调用这个偏移定位处的函数指针对应的虚函数,这就是动态绑定函数的解析过程
cusoon 2007-11-22
  • 打赏
  • 举报
回复
print();输出的是B print
2
A::test();输出的同上
A::print();输出为A print
1
使用虚函数来实现的多态性
liumingrong 2007-11-22
  • 打赏
  • 举报
回复
A::test();
A::print();
编译器是怎样转换this指针的?
飞哥 2007-11-22
  • 打赏
  • 举报
回复
你是想讨论虚函数的实现机制?

派生类的虚函数指针是指向新的函数地址的
所以如果你传入了一个派生类的指针,调用时候就会按照派生类去查虚函数表,然后调用的
所以打印两次B print是正确的
aipb_1 2007-11-22
  • 打赏
  • 举报
回复
有点意思,mark一下。

LZ要分析,输出为 B B A
飞哥 2007-11-22
  • 打赏
  • 举报
回复
你要分析啥

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧