1.拷贝构造函数
拷贝构造函数是构造函数的一种特殊形式应当于是构造函数的重构,它的参数通常是类类型的常量引用(const ClassName&)。因为对自定义类的传参操作时会先调用拷贝构造函数,然后拷贝函数接着传参陷入循环。编译器自己生成的拷贝构造一般是值拷贝/浅拷贝,这对内置类型来说没有什么问题,但如果类中含有指针成员(动态分配的内存),浅拷贝会导致多个对象指向同一内存空间,析构时会重复释放,导致程序崩溃或未定义行为。所以对于涉及动态资源管理的类就必须自定义拷贝函数实现深拷贝。以下是一个案例。
class A {
public:
A(int n=4) {
a = (int*)malloc(sizeof(int) * n);
if (a == nullptr) {
perror("malloc fail");
exit(-1);
}
b = n;
}
A(A& x) {
int* tmp = (int*)malloc(sizeof(int) * b);
if (tmp == nullptr) {
perror("malloc fail");
exit(-1);
}
x.a = tmp;
x.b = b;
}
private:
int* a;
int b;
};
int main() {
A p1;
A p2(p1);
}
2.赋值运算符重载
2.1运算符重载
在c++中内置类型的操作符都是由编译器自己完成的,自定义类型确实需要通过运算符重载来支持运算符操作,这是为了让对象能够使用像 +、-、<< 等运算符。不同运算符的重载方式不同,比如有的运算符通常重载为成员函数,有的可以作为非成员函数等。运算符重载的一般形式是 : 返回值类型 operator运算符(参数列表) 。在重载之后既可以直接使用运算符进行运算也可以通过调用函数的方式来实现。值得注意的是.* :: sizeof ?: . 这五个运算符不能重载。运算符重载之后和对应的内置类型的运算符的优先级和结合性一致
2.2赋值运算符重载
赋值运算符中有一些特殊的存在,例如++,--,<<,>>。他们都有不同的注意事项,在c++中为区分前置++和后置++(--同理)会在后置++中加一个int类型的参数作为区分:类名 operator++(int)(这里++可以换成--)。<<本来是移位符重载之后就叫流插入了,c++标准库里只对内置类型进行过重载对于自定义类型需要自己重载,如果要访问类的私有成员则需要设置为友元函数。<<还不能设置为成员函数,因为<<是双操作符如果设置为成员函数则默认的将第一个形参设为this指针,这样的话在使用流插入时cout要在后面不符合使用习惯性和观赏性,同时流插入还要能对多个数据进行操作。所以流插入一般形式为ostream& operator<<(ostream& 形参名, const 类名& 形参名);。>>为流提取和流插入基本一致只不过流提取的一般形式是istream& operator>>(istream& 形参名, const 类名& 形参名);
class Date
{
friend ostream& operator<<(ostream& out, const Date& d);
friend istream& operator>>(istream& out, const Date& d);
public:
Date(int year = 1900, int month = 1, int day = 1);
Date(const Date& d);
// 析构函数
~Date();
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& out, const Date& d);
3.const成员函数
const修饰的成员函数称为const成员函数,const一般加在形参后面即 返回值类型 函数名(形参)const。const成员函数是为了让const修饰的变量也能使用成员函数,因为const函数的this指针是const在前修饰是可以改变this指针的值的这就导致权限放大了,而const成员函数会把this指针改变为const 类名 const this。
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1);
Date(const Date& d);
Date& operator=(const Date& d);
~Date();
bool operator>(const Date& d)const;
bool operator==(const Date& d)const;
private:
int _year;
int _month;
int _day;
};
int main() {
Date d1(2025, 4, 24);
const Date d2(d1);
d1 = d2 + 2;
cout << (d2 > d1) << endl;
cout << (d2 == d1) << endl;
}
Date::Date(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
if (!CheckDead()) {
cout << "不合法日期->" << *this ;
}
}
bool Date::operator>(const Date& d) const {
if (_year > d._year) {
return true;
}
else if (_year == d._year && _month > d._month) {
return true;
}
else if (_year == d._year && _month == d._month && _day > d._day) {
return true;
}
return false;
}
bool Date::operator==(const Date& d)const {
return _year == d._year && _day == d._day && _month == d._month;
}

被折叠的 条评论
为什么被折叠?



