类的构造函数、拷贝构造函数、赋值运算符和析构函数

class MyString
{
public:
    //构造函数
    MyString(const char *str=NULL);
    //拷贝构造函数
    MyString(const MyString &other);
    //赋值运算符
    MyString &operator=(const MyString &other);
    //析构函数
    ~MyString();
private:
    char *mdata;
};

一、构造函数

//构造函数
MyString::MyString(const char *str=NULL)
{
    if(str==NULL)
    {
        mdata=new char[1];
        mdata="\0";
    }
    else
    {
        int len=strlen(str);
        mdata=new char[len];
        strcpy(mdata,str);
    }  
}

1、定义

   每个类都分别定义了它的对象初始化的方式,类通过一个或者几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数。构造函数的任务是初始化类的数据成员,无论何时只要类的对象被创建,就会执行构造函数。

2、特征

1)构造函数的名字和类名相同;构造函数没有返回类型;

2)类可以包含多个构造函数,不同的构造函数之间必须在参数数量和参数类型上有所区别。

3)当类没有声明任何构造函数时,编译器会自动生成默认构造函数。

3、注意

1)合成的默认构造函数只适合非常简单的类,对于一个普通的类来说,必须定义它自己的默认构造函数。

2)注意构造函数初始值列表的使用

二、拷贝构造函数

//拷贝构造函数
MyString::MyString(const MyString &other)
{
    int len=strlen(other.mdata);
    mdata=new char[len];
    strcpy(mdata,other.mdata);
}

1、定义

如果一个构造函数的第一个参数是自身的引用,且任何额外的参数都有默认值,则此构造函数是拷贝构造函数。

2、特征

1)拷贝构造函数的第一个参数必须是引用类型。如果其参数不是引用类型则调用永远也不会成功,因为为了调用拷贝构造函数,我们必须拷贝它的实参名单为了拷贝实参,我们又需要调用拷贝构造函数,如此无限循环。

2)如果我们没有为一个类定义拷贝构造函数,编译器会为我们定义一个。与合成的默认构造函数不同,即使我么定义了其他构造函数,编译器也会为我们合成一个拷贝构造函数。

3、应用

1)对类类型的成员,会使用其拷贝构造函数来拷贝;内置类型的成员则直接拷贝。

2)如果想阻止拷贝,就将拷贝构造函数和拷贝赋值运算符声明为私有的,并且故意不去实现他们,这样,即便friend函数也无法完成拷贝了。

三、赋值运算符

//赋值运算符
MyString & MyString::operator=(const MyString &other)
{
    //检查自赋值
    if(this==&other)
        return*this;
    delete []mdata;
    //分配新的资源,并复制内容
    int len=strlen(other.mdata);
    mdata=new char[len];
    mdata=other.mdata;
    return *this;
}

1、定义

赋值运算符就是一个名为operator=的函数,类似于其他任何函数,运算符函数也有一个返回类型和一个参数列表。

2、特征

1)赋值运算符通常应该返回一个指向其左侧运算对象的引用。

2)如果一个类未定义自己的拷贝赋值运算符,编译器会为它生成一个合成拷贝赋值运算符。

四、析构函数

//析构函数
MyString::~MyString()
{
    delete []mdata;
}

1、定义

析构函数执行与构造函数相反的操作,析构函数释放对象的资源,一、并销毁对象的非static数据成员。

2、调用

1)变量在离开其作用域时被销毁

2)当一个对象被销毁时,其成员被销毁

3)容器(无论是标准库容器还是数组)被销毁时,其元素被销毁

4)对于动态分配的对象,当对指向他的指针执行delete运算符时被销毁

3、注意

1)析构函数不接受参数,不能被重载,对于一个给定的类,只会有唯一一个析构函数。

2)当一个类作为基类会派生出其他子类时,它的析构函数应该为virtual的,不然会造成内存泄露。

五、总结

如果一个类需要一个析构函数,它肯定也需要一个拷贝构造函数和一个拷贝赋值运算符。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值