Re:从零开始的C++世界——类和对象(中)
文章目录
- 前言
- 1. 类的默认成员函数
- 2. 构造函数
- 🍎概念
- 🍎特点
- 🍌特点一
- 🍌特点二
- 🍌特点三
- 🍌特点四
- 🍌特点五
- 🍌特点六
- 🍌特性七
- 🍎总结
- 3.析构函数
- 🍎概念
- 🍎特性
- 🍌特性一
- 🍌特性二
- 🍌特性三
- 🍌特性四
- 🍌特性五
- 4. 拷⻉构造函数
- 🍎概念
- 🍎特性
- 🍌特性一
- 🍌特性二
- 🍌特性三
- 🍌特性四
- 🍎总结
- 5. 赋值运算符重载
- 🍎 运算符重载
- 🍎赋值运算符重载
- 🍎特性
- 🍌特性一
- 🍌特性二
- 🍌特性三
- 🍌特性四
- 🍌特性五
- 6.const成员函数
- 🍎const 修饰类的成员函数
- 🍎思考
- 🍌问题一
- 🍌问题二
- 🍌问题三
- 🍌问题四
- 7.取地址运算符重载
- 总结
前言
本篇主要介绍类的6个默认成员函数,这篇文章很重点!
1. 类的默认成员函数
如果一个类中什么成员都没有,简称为空类(如下)
class Date { };
空类中什么都没有吗?
并不是的,任何一个类在我们不写的情况下,都会自动生成下面6个默认成员函数。
需要注意的是这6个中最重要的是前4个,最后两个取地址重载不重要,我们稍微了解⼀下即可。其次就是C++11以后还会增加两个默认成员函数,移动构造和移动赋值,这个我们后⾯再讲解。
默认成员函数很重要,也⽐较复杂,我们要从两个⽅⾯去学习:
• 第⼀:我们不写时,编译器默认⽣成的函数⾏为是什么,是否满⾜我们的需求。
• 第⼆:编译器默认⽣成的函数不满⾜我们的需求,我们需要⾃⼰实现,那么如何⾃⼰实现?
2. 构造函数
🍎概念
对于下面 Date 类,可以通过 Init 公有的方法给对象设置内容,但是如果每次创建对象都调用该方法设置信息,未免有点麻烦,那能否在对象创建时,就将信息设置进去呢?
class Date { public: void Init(int year, int month, int day) { _year = year; _month = month; _day = day; } void Print() { cout Date d1; d1.Init(2022, 5, 1); d1.Print(); Date d2; d2.Init(2022, 7, 1); d2.Print(); return 0; } public: //无参的构造函数 Date () { _year = 1; _month = 1; _day = 1; } //带参的构造函数 Date(int year, int month, int day) { _year = year; _month = month; _day = day; } //打印 void Print() { cout Date d1; //调用无参的构造函数 d1.Print(); Date d2(2000, 10, 1); //调用带参的构造函数 d2.Print(); return 0; } public: //全缺省的构造函数 Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } //打印 void Print() { cout Date d1; d1.Print(); Date d2(2000, 10, 1); d2.Print(); return 0; } public: void Print() { cout Date d1; // 没有定义构造函数,对象也可以创建成功,因为此处调用的是编译器生成的默认构造函数 d1.Print(); return 0; } public: // 全缺省的构造函数 Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } void Print() { cout cout Date d1(2022, 9, 1); d1.Print(); return 0; } public: // 构造函数 Stack(int capacity = 2) { _a = (int*)malloc(sizeof(int) * capacity); if (_a == nullptr) { cout free(_a); _a = nullptr; } private: int* _a; int _top; int _capacity; }; int main() { Stack st; return 0; } public: // 构造函数 Date() {} // 析构函数 ~Date() {} private: int _year; int _month; int _day; } public: //构造函数 Stack(int capacity = 10) { _a = (int*)malloc(sizeof(int) * capacity); if (_a == NULL) { exit(-1); } _top = 0; _capacity = capacity; } //析构函数 ~Stack() { free(_a); _a = nullptr; _top = _capacity = 0; } private: int* _a; int _top; int _capacity; }; //队列 class MyQueue { public: void push(int x) { //操作 ... } int pop() { //操作 ... } private: Stack _st1; Stack _st2; }; int main() { MyQueue q; return 0; } public: //构造函数 Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } //拷贝构造 Date(const Date& d) { _year = d._year; _month = d._month; _day = d._day; } private: int _year; int _month; int _day; }; int main() { Date d1(2021, 5, 31); Date d2(d1); // 用已存在的对象d1创建对象d2 return 0; } public: Date(int year = 0, int month = 1, int day = 1)// 构造函数 { _year = year; _month = month; _day = day; } Date(Date d)// 拷贝构造函数 { _year = d._year; _month = d._month; _day = d._day; } private: int _year; int _month; int _day; }; int main() { Date d1(2022, 9, 1); Date d2(d1); // 用已存在的对象d1创建对象d2 return 0; } public: Date(int year = 0, int month = 1, int day = 1)// 构造函数 { _year = year; _month = month; _day = day; } void Print() { cout Date d1(2021, 5, 30); Date d2(d1); // 用已存在的对象d1创建对象d2 d1.Print(); d2.Print(); return 0; } public: Stack(int capacity = 4) { _a = (int*)malloc(sizeof(int) * capacity); if (_a == nullptr) { cout free(_a); _a = nullptr; } private: int* _a; int _top; int _capacity; }; int main() { Stack st1; Stack st2(st1); return 0; } public: //构造函数 Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; }; int main() { Date d1(2022, 9, 1); Date d2(2022, 9, 1); d1 == d2; return 0; } public: Date(int year = 0, int month = 1, int day = 1) // 构造函数 { _year = year; _month = month; _day = day; } // 等价于 bool operator==(Date* this, const Date& d2) // 这里需要注意的是,左操作数是this指向的调用函数的对象 bool operator==(const Date& d) // ==运算符重载 { return _year == d._year && _month == d._month && _day == d._day; } private: int _year; int _month; int _day; }; int main() { Date d1(2022, 9, 1); Date d2(2022, 9, 1); d1.operator==(d2); d1 == d2;//同上,编译器会自动识别转换为 d1.operator==(d2) --- d1.operator(&d1, d2); return 0; } public: Date(int year = 1, int month = 1, int day = 1) // 构造函数 { _year = year; _month = month; _day = day; } //private: public://这里破坏封装使得可以在类外访问成员 int _year; int _month; int _day; }; bool operator==(const Date& d1, const Date& d2)// ==运算符重载函数 { return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day; } int main() { Date d1(2022, 9, 1); Date d2(2022, 9, 1); operator==(d1, d2); // 可以这样调用,但是这样可读性很差,还不如写一个函数 d1 == d2; //同上,如果没有重载会报错,如果重载了它会转换为 operator==(d1, d2); cout public: // 默认生成的析构函数,内置类型成员不做处理,自定义类型成员会去调用它的析构函数 Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } void Print() // 打印函数 { cout if (this != &d) { _year = d._year; _month = d._month; _day = d._day; } return *this; } private: int _year; int _month; int _day; }; int main() { Date d1(2022, 9, 1); Date d2(2022, 9, 2); Date d3(d1); // 拷贝构造 -- 一个存在的对象去初始化另一个要创建的对象 d3 = d2 = d1; // 赋值重载/复制拷贝 -- 两个已经存在对象之间赋值 (d3 = d2) = d1; // 赋值重载/复制拷贝 -- 两个已经存在对象之间赋值 return 0; } public: Date(int year = 1900, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } void Print() // 打印函数 { cout Date d1; Date d2(2022, 9, 1); // 这里d1调用的编译器生成 operator= 完成拷贝,d2和d1的值也是一样的。 d1 = d2; d1.Print(); d2.Print(); return 0; } public: // 构造函数 Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } // 打印函数 void Print1() { cout const Date d1(2022, 9, 1); d1.Print1(); return 0; } public: // 构造函数 Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } // const成员函数 void Print2() const { cout const Date d1(2022, 9, 1); d1.Print2(); return 0; } public: Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } //普通对象 取地址操作符重载 Date* operator&() { return this; } //const对象 取地址操作符重载 const Date* operator&() const { return this; } private: int _year; int _month; int _day; }; int main() { Date d1(2021, 10, 13); const Date d2(2021, 10, 14); cout
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。