C++琐记

</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;
}


  1. 用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;
}



  1. 多态从哪一层开始,以及父、子类接口权限的变更

从声明了虚函数的那一层向下都具有多态功能


#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.构造函数为什么不能是虚函数

百度一下,有详细解答。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值