类与对象-----中篇
1:类的6个默认成员函数
2:构造函数
1):概念
一个特殊的成员函数,名字与类名相同,创建类类型对象的时候,由编译器自己调用,在对象的生命周期中且调用一次,以保证每个数据成员都有一个合适的初始值
2):构造函数的特性:
- 函数名与类名相同
- 没有返回值
- 有初始化列表(可以不用)
- 对象实例化时编译器自动调用对应的构造函数
- 构造函数可以重载
test.h
class Date {
private:
int _year;
int _month;
int _day;
public:
Date();
Date(int year, int month, int day);
};
test.cpp
//无参构造函数
Date::Date() {
}
//带参构造函数
Date::Date(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
int main() {
Date d1;//调用无参构造函数
Date d2(1990, 1, 1);//调用含参构造函数
}
- 如果没有显示定义时,编译器会提供一个默认的构造函数
test.h
class Date {
private:
int _year;
int _month;
int _day;
public:
//Date(int year,int month,int day)
};
test.cpp
#include"test.h"
//如果用户显式定义了构造函数,编译器将不再生成
//Date::Date(int year, int month, int day) {
// _year = year;
// _month = month;
// _day = day;
//}
int main() {
//没有定义构造函数,对象也可以生成成功,因此此处调用的是编译器生成的默认构造函数
Date d;
return 0;
}
- 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认成员函数。
- 构造函数不能用const修饰(因为const修饰成员函数时,该函数不能修改成员变量,但构造函数要修改类的成员变量,所以不能用const修饰)
3):默认构造函数
未提供显式初始值的构造函数
4):构造函数的作用
- 构建对象
- 初始化对象
- 类型转化
3:析构函数
1):概念:与构造函数功能相反,析构函数不是完成对象的销毁,局部对象的销毁是由编译器完成的,而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作。
2):特性
- 析构函数名是在类名前加上字符~;
- 无参数返回值
- 一个类有且仅有一个析构函数,当用户未显示定义时,编译器会默认生成析构函数
- 对象声明周期结束时,c++编译系统自动调用析构函数
- 注意析构函数不是删除对象,而是做一些清理工作
test.h
class Line {
public:
void setLine(double len);
double getLine();
Line();
~Line();
private:
double length;
};
test.cpp
#include"test.h"
#include<assert.h>
#include<malloc.h>
typedef int DataType;
SeqList::SeqList(int capacity=10) {
_array = (DataType*)malloc(capacity * sizeof(DataType));
assert(_array);
_capacity = capacity;
_size = 0;
}
SeqList::~SeqList() {
if (_array) {
free(_array);
_array = nullptr;
_capacity = 0;
_size = 0;
}
}
void SeqList::TestSeqList() {
}
int main() {
SeqList s;
s.TestSeqList();
system("pause");
return 0;
}
4:拷贝构造函数
test.h
class Date {
private:
int _year;
int _month;
int _day;
public:
Date(int year, int month, int day);
Date(const Date& d);
void print();
};
test.cpp
#include"test.h"
Date::Date(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
Date::Date(const Date& d) {
_year = d._year;
_month = d._month;
_day = d._day;
}
void Date::print() {
cout << _year << "-" << _month << "-" << _day << endl;
}
int main() {
Date d1(1990, 1, 1);
Date d2(d1);
d1.print();
d2.print();
system("pause");
return 0;
}
概念:
只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。
特性:
- 拷贝构造函数时构造函数的一个重载形式
- 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。
- 若未显示定义,编译器默认生成拷贝构造函数,默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝称为浅拷贝,也称值拷贝
5:赋值操作符重载
概念:
对于类类型的对象,我们需要对“=”进行重载,已完成类类型之间的赋值
test.h
class Date {
private:
int _year;
int _month;
int _day;
public:
Date(int year, int month, int day);
Date& operator=(const Date& d);
void print();
};
test.cpp
#include"test.h"
Date::Date(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
Date& Date::operator=(const Date& d) {
if (this != &d) {
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
void Date::print() {
cout << _year << "-" << _month << "-" << _day << endl;
}
int main() {
Date d1(1990, 1, 1);
Date d2(2000, 1, 1);
d1.print();
d2.print();
d1 = d2;
d1.print();
system("pause");
return 0;
}
6:const成员函数
将const修饰的类成员函数,称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。
test.h
class Date {
public:
void Display();
void Display()const;
private:
int year;
int month;
int day;
};
test.cpp
#include"test.h"
void Date::Display() {
cout << year << "-" << month << "-" << day << endl;
}
void Date::Display()const {
cout << year << "-" << month << "-" << day << endl;
}
int main() {
Date d1;
d1.Display();
const Date d2;
d2.Display();
system("pause");
return 0;
}
7:取地址及const修饰的取地址操作符重载
test.h
class Date {
private:
int _year;
int _month;
int _day;
public:
Date* operator&();
const Date* operator&()const;
};
test.cpp
#include"test.h"
Date* Date::operator&() {
return this;
}
const Date* Date::operator&()const {
return this;
}