</pre>最近在找工作,准备的C++方向,所以做了一些复习,尤其是阅读了《深入探索C++对象模型》。就自己和同学们的面试经验来看,有不知一个面试官推荐看这本书了。</p><p>花了两天时间看完了这书,确实对C++有了更加深入的认识。知道了C++的很多不足与实现的关隘。同时也更加把C++看作一门“高级”语言了:拥有一些无法解决的问题和二义性的特点。</p><p>在下面把自己觉得有意思,或者以前不知道的几个点列举一下,也算是给这本书做一下自己的笔记吧。</p><p></p><ol class="ol1"><li class="li1">调用哪个函数?</li></ol><p></p><p class="p2"><pre name="code" class="cpp">class Test {
private:
int mm;
public:
Test() : mm(2) {}
Test( int m = 3) : mm(m) {}
int getMM() { return mm; }
};
int main() {
Test *t = new Test();
return 0;
}
那么,调用的是哪一个构造函数?答案是编译错误,编译器无法判断应该调用哪一个
另外,在函数参数不同的情况下,返回值也可以不同
class Test {
public:
void func() {}
int func( int m ) {return m; }
};
int main() {
Test t;
t.func();
return 0;
}
- 用struct模仿一个类
同学面试时遇到的,下面简单实现一下。把基本路线确定了,至于继承等特性读完《深度探索C++对象模型》按照基本路线也可以实现。
struct Test {
Test *t_this;
void (*Constructor)( Test*, int );
int mm;
int (*getMM)( Test* );
};
int outerGetMM( Test* inStruct ) {
return inStruct->mm;
}
void Test_constructor( Test* hoster, int m ) {
hoster->mm = m;
hoster->getMM = outerGetMM;
}
int main() {
Test t;
t.Constructor = Test_constructor;
t.Constructor( &t, 3 );
int result = t.getMM( &t );
return 0;
}
- 多态从哪一层开始,以及父、子类接口权限的变更
从声明了虚函数的那一层向下都具有多态功能
#include <iostream>
using namespace std;
class TestA {
public:
void func() { cout <<"It's in TestA." << endl; }
};
class TestB : publicTestA {
public:
virtual void func() {cout << "It's in TestB." << endl; }
};
class TestC : publicTestB {
public:
void func() { cout <<"It's in TestC." << endl; }
};
class TestD : publicTestC {
private:
void func() { cout <<"It's in TestD." << endl; }
};
int main() {
TestA *t0 = newTestB();
TestC *t1 = newTestD();
t0->func();
t1->func();
TestD *t2 = newTestD();
t2->func(); // 调用失败
return 0;
}
在这个继承层次中,自 B类往下都拥有多态性质;
而若父类对一个方法声明为public,子类覆盖了这个方法并且把这个方法声明为private,那么通过子类的对象是不可以调用这个方法的。但是若是用父类的指针指向子类的对象,是可以调用这个方法的,而且调用的是子类版本的方法。
所以上面代码的输出为:
It's in TestA.
It's in TestD.
4.声明一个不可以被继承的类
将其析构函数声明为private,编译的时候直接就不能被继承
为什么将构造函数声明为private,编译的时候仍然会报错
5.纯虚函数是可以在子类的构造函数中被静态调用的
#include <iostream>
using namespace std;
class Base {
public:
Base() : mm(9) {}
inline virtualvoid func() const = 0;
public:
int mm;
virtual ~Base();
};
inline void Base::func()const {
cout <<"It's in Base." << endl;
}
class Derived : publicBase {
public:
Derived() { Base::func(); }
void func() const {cout << "It's in Derived." << endl; }
~Derived() {}
};
int main() {
Derived t;
return 0;
}
《深入探索C++对象模型》原话:
C++新手常常很惊讶地发现,一个人竟然可以定义和调用一个pure virtual function;不过它只能被静态地调用,不能经由虚拟机制调用
… …
… pure virtual destructor:class设计者一定得定义它。因为每一个derived class destructor会被编译器加以扩张,以静态调用的方式调用其“每一个virtual base class”以及“上一层base class”的destructor。因此,只要缺乏任何一个base class destructors的定义,就会导致链接失败。
6.构造函数为什么不能是虚函数
百度一下,有详细解答。。。