c++随笔

来源:互联网 发布:梦幻西游mac版更新 编辑:程序博客网 时间:2024/05/29 05:56

1......virtual关键字:

基函数定义了virtual,继承类的该函数也就具有virtual属性。定义了virtual属性后,如果用基类类型的指针指向子类,可以用该指针直接调用子类中对应的函数。可以说虚函数就是c++多态性的一种体现。

纯虚函数是一种特殊特殊的函数,在基类并不给出有意义的实现,而留给子类实现。

 理论上在基类采用virtual关键字,不进行实现就可以实现纯虚函数,拥有纯虚函数的类不能被实例化。但是,如果这种情况下进行了实例化,编译器不能再编译阶段发现问题,只能在链接阶段报错,所以,标准的声明纯虚函数的方法如下:

virtual ~CException() = 0;

这样,一旦声明了该类的实例,就会产生如下错误
错误    C2259    “CException”: 不能实例化抽象类   


2.......初始化列表

三种情况下只能使用初始化列表对成员变量进行初始化,而不可以在构造函数中对其初始化。

常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面

引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面

没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。

对第三种情况,例子如下:

struct Test1{    Test1(int a):i(a){}    int i ;};struct Test2{    Test1 test1 ;    Test2(Test1 &t1)    {        test1 = t1 ;    }};

以上代码无法通过编译,因为Test2的构造函数中test1 = t1这一行实际上分成两步执行。

1. 调用Test1的默认构造函数来初始化test1

2. 调用Test1的赋值运算符给test1赋值

但是由于Test1没有默认的构造函数,所谓第一步无法执行,故而编译错误。正确的代码如下,使用初始化列表代替赋值操作。

struct Test2{    Test1 test1 ;    Test2(Test1 &t1):test1(t1){}}

 
3....static

与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。


4...new
int *a = new int(5)
注意,new返回的只能是指针,new后面所跟随的是类
 

5...模板类的继承
template<typenameT>
class QList
如果要继承QList,应该采取下列语法,因为模板类不可以直接继承
classtestList: publicQList<QString>
 

6...explic关键字

关键字explicit可以禁止“单参数构造函数”被用于自动类型转换
class Stack
{
explicit Stack(int size);
};
没有explicit的话Stack s = 40;能编译通过
而有explicit则不能,必需Stack s(40);

 7...拷贝构造函数

#include <iostream>using namespace std;class CExample {private:    int a;public:    //构造函数    CExample(int b)    { a = b;}        //拷贝构造函数    CExample(const CExample& C)    {        a = C.a;    }    //一般函数    void Show ()    {        cout<<a<<endl;    }};int main(){    CExample A(100);    CExample B = A; // CExample B(A); 也是一样的     B.Show ();    return 0;} 

在三种情况下会调用拷贝构造函数(1)对象以值传递的方式作为函数参数时(2)对象以值传递的方式作为函数返回时(3)直接拷贝的
拷贝构造函数可以分为浅拷贝和深拷贝。默认的拷贝构造函数就是浅拷贝。
在浅拷贝时,只处理对象中的数据成员。
如果出现比如说在构造函数中动态在堆中分配了内存空间,注意,浅拷贝的两个对象实际上是公用同一块内存空间,这样在析构时就会出现错误。
深拷贝的代码如下
class Rect{public:    Rect()      // 构造函数,p指向堆中分配的一空间    {        p = new int(100);    }    Rect(const Rect& r)    {        width = r.width;        height = r.height;        p = new int;    // 为新对象重新动态分配空间        *p = *(r.p);    }    ~Rect()     // 析构函数,释放动态分配的空间    {        if(p != NULL)        {            delete p;        }    }private:    int width;    int height;    int *p;     // 一指针成员};



 
 
 
0 0