关于对象模型的几个面试题(很基础,但坑较多)
2017-04-08 00:09
423 查看
可能是因为光是看书,关于看到的知识点也不会去深思各种各样的场景去构造,导致遇到一些很基础的问题都会犯二,写此篇博客,特警示自己:
学知识,最重要的是思考!!!
如果关于对象模型你还有那么一点兴趣,那么可以继续向下看,看看自己是否可以完全答对。。。
1.面试题(选择题):
下面我贴出的是主要的代码片,头文件以及using namespace std;需要自行添加哦!
选项:
A pA、pB、pC的取值相同
B、 pC 和 pA不相同
C、pB和pC不相同
D、pC不等于pA,也不等于pB。
C类对象模型:
解析:在继承体系中,当用一个基类的指针或引用指向派生类对象时(赋值兼容规则),这时会将派生类对象的地址偏移一个合适偏移量,因为派生类对象也是一个基类对象,实际也就是让基类指针指向派生类中属于基类的那部分。所以一般先继承的那个类(基类)的指针和派生类的对象的地址相等。不知道你有没有听懂呢?(无奈脸)
2.问下列程序会输出什么?
1)A类和B类是两个不相关的类
A类和B类没有关系,所以pb肯定调用的是B类的fun函数,但是pb又是被强制指向A类对象的,
那么肯定会打印前A类对象前四个字节的值,也就是1。(因为B类大小就是4个字节)。
图形解析如下:
2)B类公有继承自A类时,程序会输出什么?
解析:pb仍然会去调用B类的fun函数,而B类的fun函数需要打印m_c的值,对象a中并没有m_c,那块空间未定义,所以程序最终输出随机值或者程序崩溃。
图解如下:
3).B公有继承自A,且将A中的fun函数定义为虚函数后
输出结果为: 1 2
对象模型:
4)B公有继承自A,且A中的fun为普通函数,仅将B类fun函数定义为虚函数.
输出什么?——–>程序崩溃
不知道你看完之后是什么感受?你有没有全部答对呢?如果全部答对了,那么说明你对于继承/多态理解的特别透彻了,希望你不要像我一样惨~
学知识,最重要的是思考!!!
如果关于对象模型你还有那么一点兴趣,那么可以继续向下看,看看自己是否可以完全答对。。。
1.面试题(选择题):
下面我贴出的是主要的代码片,头文件以及using namespace std;需要自行添加哦!
class A { public : A() :_a(1) {} virtual void FunTestA() {} int _a; }; class B { public: B() :_b(2) {} virtual void FuntestB() {} int _b; }; class C :public A, public B { public : C() :A() , B() , _c(3) {} int _c; }; void Fun() { C c; cout << sizeof(c) << endl; A* pA = &c; B* pB = &c; C* pC = &c; } int main() { Fun(); return 0; }
选项:
A pA、pB、pC的取值相同
B、 pC 和 pA不相同
C、pB和pC不相同
D、pC不等于pA,也不等于pB。
C类对象模型:
解析:在继承体系中,当用一个基类的指针或引用指向派生类对象时(赋值兼容规则),这时会将派生类对象的地址偏移一个合适偏移量,因为派生类对象也是一个基类对象,实际也就是让基类指针指向派生类中属于基类的那部分。所以一般先继承的那个类(基类)的指针和派生类的对象的地址相等。不知道你有没有听懂呢?(无奈脸)
2.问下列程序会输出什么?
1)A类和B类是两个不相关的类
class A { public : A() { m_a = 1; m_b = 2; } void fun() { cout << m_a <<" "<< m_b << endl; } private : int m_a; int m_b; }; class B { public : B() { m_c = 3; } void fun() { cout << m_c << endl; } private : int m_c; }; void Fun() { A a; B* pb = (B*)(&a); pb->fun(); } int main() { Fun(); return 0; }
A类和B类没有关系,所以pb肯定调用的是B类的fun函数,但是pb又是被强制指向A类对象的,
那么肯定会打印前A类对象前四个字节的值,也就是1。(因为B类大小就是4个字节)。
图形解析如下:
2)B类公有继承自A类时,程序会输出什么?
class A { public : A() { m_a = 1; m_b = 2; } void fun() { cout << m_a <<" "<< m_b << endl; } private : int m_a; int m_b; }; class B:public A { public : B() :A() { m_c = 3; } void fun() { cout << m_c << endl; } private : int m_c; }; void Fun() { A a; B* pb = (B*)(&a);//切记:这里是派生类的指针指向基类对象 pb->fun(); } int main() { Fun(); return 0; }
解析:pb仍然会去调用B类的fun函数,而B类的fun函数需要打印m_c的值,对象a中并没有m_c,那块空间未定义,所以程序最终输出随机值或者程序崩溃。
图解如下:
3).B公有继承自A,且将A中的fun函数定义为虚函数后
输出结果为: 1 2
class A { public : A() { m_a = 1; m_b = 2; } virtual void fun()//虚函数 { cout << m_a <<" "<< m_b << endl; } private : int m_a; int m_b; }; class B:public A { public : B() :A() { m_c = 3; } void fun()//重写 { cout << m_c << endl; } private : int m_c; }; void Fun() { A a; B b; B* pb = (B*)(&a);//切记:这里是派生类的指针指向基类对象,不会形成多态 pb->fun();//在A类的虚表内找fun函数(调用的是A类的fun函数),输出1和2 } int main() { Fun(); return 0; }
对象模型:
4)B公有继承自A,且A中的fun为普通函数,仅将B类fun函数定义为虚函数.
输出什么?——–>程序崩溃
class A { public : A() { m_a = 1; m_b = 2; } void fun()//普通函数 { cout << m_a <<" "<< m_b << endl; } private : int m_a; int m_b; }; class B:public A { public : B() :A() { m_c = 3; } virtual void fun()//虚函数 { cout << m_c << endl; } private : int m_c; }; void Fun() { A a; B b; B* pb = (B*)(&a); pb->fun();//要去a对象的前四个字节取虚表地址,从而去找fun函数,可惜a对象中并没有虚表,所以程序崩溃 } int main() { Fun(); return 0; }
不知道你看完之后是什么感受?你有没有全部答对呢?如果全部答对了,那么说明你对于继承/多态理解的特别透彻了,希望你不要像我一样惨~
相关文章推荐
- Java面试题——关于String创建几个对象问题
- 关于ADO对象的筛选,只是一些基础,至少省去了重新构造Where 条件的麻烦~!
- 我们手机平台的几个基础模型
- JAVA面试题解惑系列(二)——到底创建了几个String对象?
- JAVA面试题解惑系列(二)——到底创建了几个String对象?
- 关于 new String("xyz")创建几个对象的理解
- 关于 new String("xyz")创建几个对象的理解
- C++对象模型之一 关于对象笔记
- JAVA面试题解惑系列(二)——到底创建了几个String对象?
- JAVA面试题解惑系列(二)——到底创建了几个String对象?
- JAVA面试题解惑系列(二)——到底创建了几个String对象?
- 手机平台的几个基础模型
- 关于String a=new String("a")创建几个对象问题的正确答案
- 解读Document Library关于权限的对象模型
- JAVA面试题解惑系列(二)——到底创建了几个String对象?
- 我们手机平台的几个基础模型
- Lesson 1 关于对象模型
- 关于 new String("xyz")创建几个对象的理解
- 基础:声明了几个对象,==和equals的区别
- JAVA面试题解惑系列(二)——到底创建了几个String对象?