构造函数
默认构造函数
默认构造函数无需手写。对象定义方式:
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;
}