C++类的构造函数、析构函数、赋值运算符函数、拷贝构造函数、移动赋值运算符函数、移动拷贝构造函数

构造函数

默认构造函数

默认构造函数无需手写。对象定义方式:

class DOT
{
private:
    int v;
};
int main()
{
    DOT a;
    return 0;
}

自定义构造函数

要求:函数名与类名一致、函数无返回值、公有成员。
自定义构造函数有两种写法,其中type 2可以使用相同的变量名:

class DOT
{
private:
    int v1, v2;

public:
    DOT(int _v1, int _v2)// type 1
    {
        v1 = _v1;
        v2 = _v2;
    }
    DOT(int v1, int _v2) : v1(v1), v2(_v2) {}//type 2
};
int main()
{
    DOT a(10, 20);
    return 0;
}

注意:如果自定义了构造函数,那么默认构造函数就无法生成,那么使用DOT a;这样的定义就会报错,则只需要加上一个默认构造函数即可:DOT(){}

析构函数

默认析构函数

默认析构函数无需手写。

自定义析构函数

要求:函数名为~加类名、函数无返回值、无参数、公有成员、每个类仅有一个析构函数 。
一般用于释放动态分配的内存

class DOT
{
private:
    int v1, v2;

public:
    DOT(int v1, int _v2) : v1(v1), v2(_v2) {}
    ~DOT() {} //析构函数
};

赋值运算符函数

一般来说,默认赋值运算符函数足以解决对象之间的赋值问题。但是,当类包含有指针数据成员时,默认赋值运算符函数常会引发指针悬挂的问题。

    DOT &operator=(const DOT &x)
    {
        v1 = x.v1;
        v2 = x.v2;
        return *this;
    }

使用:

int main()
{
    DOT a(10, 20), b;
    b = a;
}

拷贝构造函数

拷贝构造函数的参数是一个对象。函数内容类似于赋值运算符函数,但使用方法不同。

class DOT
{
private:
    int v1, v2;

public:
    DOT() {}
    DOT(int v1, int _v2) : v1(v1), v2(_v2) {}
    DOT(DOT &x) { *this = x; } //拷贝构造函数
    ~DOT() {}
    DOT &operator=(const DOT &x)
    {
        v1 = x.v1;
        v2 = x.v2;
        return *this;
    }
};
int main()
{
    DOT a(10, 20);
    DOT b(a); //利用拷贝构造函数来生成对象
    return 0;
}

移动赋值运算符函数 和 移动拷贝构造函数

默认:只有当类内没有定义赋值运算符函数拷贝构造函数析构函数时,编译器才会自动生成移动赋值运算符函数 和 移动拷贝构造函数。
移动赋值运算符函数 和 移动拷贝构造函数的参数都是一个右值引用;

class DOT
{
	······
    DOT(DOT &&x) { *this = x; } //移动拷贝构造函数
    DOT &operator=(const DOT &&x) //移动赋值运算符函数
    {
        v1 = x.v1;
        v2 = x.v2;
        return *this;
    }
    DOT operator+(const DOT &x)
    {
        return DOT(v1 + x.v1, v2 + x.v2);
    }
};
int main()
{
    DOT a(10, 20);
    DOT b(a);
    DOT c(a + b); //括号内的a+b为右值,需要移动拷贝构造函数
    DOT d = a + b; //a+b为右值,需要移动赋值运算符函数
    return 0;
}

小结

class DOT
{
private:
    int v1, v2;

public:
    DOT() {}                                  //默认构造函数
    DOT(int v1, int _v2) : v1(v1), v2(_v2) {} //构造函数
    ~DOT() {}                                 //析构函数
    DOT &operator=(const DOT &x)              //赋值运算符函数
    {
        v1 = x.v1;
        v2 = x.v2;
        return *this;
    }
    DOT(DOT &x) { *this = x; }    //拷贝构造函数
    DOT(DOT &&x) { *this = x; }   //移动拷贝构造函数
    DOT &operator=(const DOT &&x) //移动赋值运算符函数
    {
        v1 = x.v1;
        v2 = x.v2;
        return *this;
    }
    DOT operator+(const DOT &x)
    {
        return DOT(v1 + x.v1, v2 + x.v2);
    }
};
int main()
{
    DOT a(10, 20);
    DOT b(a);      //利用拷贝构造函数来生成对象
    DOT c(a + b);  //括号内的a+b为右值,需要移动拷贝构造函数
    DOT d = a + b; //a+b为右值,需要移动赋值运算符函数
    return 0;
}
原创文章 1 获赞 0 访问量 57

猜你喜欢

转载自blog.csdn.net/Arsuviin/article/details/105868165