C++ 类的默认函数

用户自定义一个类,简单的可以看成是一个新的类型,与C++标准里面的数据类型使用差不多。但在面向对象编程中,我们知道任何一个对象必须要通过构造函数才能创建,以及可以将一个对象拷贝给另一个对象,将一个对象作为参数传递给一个函数等。

C++默认函数
  • 一个没有任何成员函数的类,其至少有如下四个默认函数
    • 默认构造函数
    • 默认拷贝构造函数
    • 默认“=”运算符重载函数
    • 析构函数

既然是默认函数,那也就是说即便类里面一个成员函数没有,这几个函数仍然存在(想来也是必然,就算啥成员函数都没有,但总需要创建对象,赋值,作为参数传递等),先看下几个默认函数长什么样,这里只是为了更加形象的表示,实际类中是看不到这几个函数的,**一旦类里面有与这几个函数同名的函数,那相
应的默认函数都被覆盖了**

class Base{
private:
    int a;
    int b;
public:
    Base(){};               //默认构造函数
    Base(const Base & cb)    //默认拷贝构造函数
    {
        //利用对象b对类对象成员属性进行简单的拷贝
        this->a = cb.a;
        this->b = cb.b;
    }
    Base & operator=(const Base & cb)  //默认“=”运算符重载函数
    {
        //利用对象b对类对象成员属性进行简单的拷贝
        this->a = cb.a;
        this->b = cb.b;        
    }
    ~Base(){}               //析构函数
};

默认构造函数用于创建对象,主要有以下两种方式
class Base{
public:
    int a;
    int b
};

Base cb;
Base * pcb = new Base();

以上两种创建对象的方式,均会调用默认构造函数调用创建对象。由于这里类B没有任何构造函数,因此直接调用默认构造函数,需要注意,默认构造函数只是为对象申明空间,而并不会将对象成员进行初始化,如下:

class Base{
public:
    int a;
    int b
};

Base cb;
Base * pcb = new Base();

cout << cb.a << endl;

// cb.a输出为一个随机值
默认拷贝构造函数,主要用在初始化、传值
  • 用一个对象初始化另一个对象
  • 将一个对象作为函数参数以值传递的方式传递(与引用方式区分)
  • 将一个对象作为函数返回值
class Base{
};

void fun(Base ba);
Base fun1();

Base cb;

Base cb1(cb);    //调用默认拷贝构造函数
Base cb2 = cb;   //调用默认拷贝构造函数
Base cb3;

fun(cb);         //调用默认拷贝构造函数
cb3 = fun1();    //调用默认拷贝构造函数

注意Base cb2 = cb; 这里是初始化,并不是赋值!

默认“=”运算符重载函数, 主要用在赋值语句
  • 赋值语句与初始化的区别:初始化是在申明对象的时候,同时对其“赋值”,是在分配内存的同时完成内存内容填充;赋值是先分配内存,再从其它对象将内容拷贝到该内存空间。

class Base{
};

void fun(Base ba);


Base cb;
Base cb2;        //调用默认构造函数

cb2 = cb;        //调用默认“=”操作符重载函数
默认析构函数:在对象销毁(可以是系统自动销毁或者用户主动销毁)时调用。

class Base{
};

int main()
{

    Base cb;         //当前作用域之后销毁cb对象,此处是main函数结束即销毁对象
    Base * pcb = new Base();   

    delete pcb;      //调用delete pcb手动销毁pcb指向的对象
    return 0;
}

需要注意默认拷贝构造函数默认“=”操作符重载函数都会检查对象是否初始化,前面提到过,默认构造函数在创建对象的时候,如果有成员变量,则不会对成员变量进行初始化,因此在利用该对象初始化其它对象或者赋值给其它对象,则会编译出错。

class Base{
public:
    int a;
};

int main()
{
    Base cb;      
    Base cb1(cb);       //编译错误提示:使用了未初始化的局部变量
    Base cb2 = cb;      //编译错误提示:使用了未初始化的局部变量
    return 0;
}

使用忠告:
  • 为自己的每个类重新编写构造函数,至少要有一个没有参数的构造函数(也即替代默认构造函数)。
  • 构造函数里面对类成员进行初始化,尽量使用初始化列表的方式
  • 如果有用对象进行初始化或者赋值、拷贝、传值,不要依赖类默认的拷贝构造与“=”运算符重载函数。牵涉到深拷贝与浅拷贝,尽量自己实现这两个函数,详细指定如何拷贝。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值