C++面向对象笔记3 (PKU)

构造函数

        成员函数的一种,名字与类名相同,可以有参数,不能有返回值

        作用是对对象进行初始化,如给成员变量赋值

        如果定义类时没写构造函数,则编译器会生成一个默认的无参数且不做任何操作的构造函数;而当定义时写了构造函数,那么默认的构造函数不会生成,如果定义的构造函数有参数,定义类的对象的时候一定要带着参数定义,例如:

class Complex {
    private:
        double real, imag;
    public:
        Complex(double r, double i = 0);
};
Complex::Complex(double r, double i) {
    real = r, imag = i;
}
Complex c1; //error,缺少构造函数的参数
Complex c1(2); // OK
Complex c1(2, 3), c2(3, 5); // OK
Complex * pc = new Complex(3, 4); // OK

        一个类可以有多个构造函数,参数个数或类型不同,它们形成重载关系

        C++11列表初始化可以用于类,只要提供与某个构造函数的参数列表匹配的内容

class CSample {
    int x;
public:
    CSample() {
        cout << "1" << endl;
    }
    CSample(int n) {
        x = n;
        cout << "2" << endl;
    }
};

int main() {
    CSample array[2] = {3};
    /*
        array[0]提供了3可用于构造函数, 输出2;
        array[1]未提供构造函数的参数, 故调用第一个构造函数, 输出1.
    */
    return 0;
}

复制构造函数

        只有一个参数,即对同类对象的用

        形如 X::X( X& ) 或 X::X( const X & ) ,后者能以常量对象作为参数

        如果没有定义复制构造函数,那么编译器会生成默认复制构造函数,默认复制构造函数完成复制功能,一个类有且仅有一个复制构造函数

class Complex {
    private:
        double real, imag;
};
Complex c1; // 调用缺省无参构造函数
Complex c2(c1); // 调用缺省的复制构造函数, 将c2初始化成和c1一样

        复制构造函数必须是传递引用,因为如果定义一个按值复制构造函数,那么编译器必须在调用的时候创建该参数的副本,这意味着必须再次调用复制构造函数,这样就会进入一个无限递归地调用过程,最终导致栈溢出

        复制构造函数起作用的情况:

        1):当用一个对象去初始化同类的另一个对象时(定义时的“=”为初始化语句而非赋值语句)

        2):如果一个函数有一个参数是类A的对象,那么该函数被调用的时,类A的复制构造函数将被调用

        3):如果一个函数的返回值是类A的对象,则函数返回时,A的复制构造函数被调用

        注意:对象间的赋值不导致复制构造函数被调用(因为目标对象已存在,不需要通过构造函数创建新对象,注意复制构造函数本身为“构造函数”)

类型转换构造函数

        定义类型转换构造函数的目的是实现类型的自动转换

        只有一个参数,而且不是复制构造函数的构造函数,一般就可以看作是转换构造函数;当需要的时候,编译系统会自动的调用转换构造函数,建立一个无名的临时对象

class Complex {
    public:
        double real, imag;
        Complex(int i) { // 类型转换构造函数
            real = i, imag = 0;
        }
        Complex(double r, double i) { real = r, imag = i; }
};
int main() {
    Complex c1(7, 8);
    Complex c2 = 12;
    c1 = 9;
    return 0;
}

析构函数

        名字与类名相同,在前面加‘~’,没有参数和返回值,一个类最多只能有一个析构函数

        析构函数在对象消亡时自动被调用,可用来做释放分配的空间等“善后工作”;如果没有定义类时未写析构函数,则编译器会生成缺省析构函数,缺省析构函数什么也不做

        

class String {
    private:
        char * p;
    public:
        String() {
            p = new char[10];
        }
        ~String();
};
String::~String() {
    delete [] p;
}

        注意1:一个局部变量的生存期是从定义开始,到包括了它的最内层的"}"为止

        注意2:程序结束时,先初始化的后析构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值