二、类
Author: XFFer_
文章目录
- 二、类
-
- 01 成员函数、对象拷贝、私有成员
- 02 构造函数详解,explicit,初始化列表
- 03 inline、const、mutable、this、static
- 04 类内初始化、默认构造函数、 =default
- 05 拷贝构造函数
- 06 重载运算符、拷贝赋值运算符、析构函数
- 07 派生类、调用顺序、访问等级、函数遮蔽
- 08 基类指针、虚纯虚函数、多态性、虚析构
- 09 友元函数、友元类、友元成员函数
- 10 RTTI、dynamic_cast、typeid、虚函数表
- 11 基类与派生类关系的详细再探讨
- 12 左值、右值、左值引用、右值引用、move
- 13 临时对象深入探讨、解析,提高性能手段
- 14 对象移动、移动构造函数、移动赋值运算符
- 15 继承的构造函数、多重继承、虚继承
- 插入课:C++文件和流
- 16 类型转换构造函数、运算符,类成员指针
01 成员函数、对象拷贝、私有成员
1 综述
2 类基础
3 成员函数
4 对象的拷贝
5 私有成员
成员函数
//Time.h
class Time {
int hour;
int minute;
int second;
void InitTime (int tmphour, int tmpminute, int tmpsecond);
};
//Time.cpp
#include "Time.h"
void Time::InitTime (int tmphour, int tmpminute, int tmpsecond)
{
hour = tmphour;
minute = tmpminute;
second = tmpsecond; //类内部定义成员函数可以之间引用成员变量
}
对象的拷贝
Time time_one;
Time time_two = time_one;
Time time_three (time_two);
Time time_four {
time_three };
默认情况下,这种类对象的拷贝,是每个成员变量逐个拷贝。如果在类中定义适当的“赋值运算符”就能够控制对象的这种拷贝行为。
02 构造函数详解,explicit,初始化列表
1 构造函数
2 多个构造函数
3 函数默认参数
4 隐式转换和explicit
5 构造函数初始化列表
构造函数
在类中,有一种特殊的成员函数,它的名字和类名相同,我们在创建类的对象时,这个特殊的成员函数就会被系统自动调用。这个成员函数,就叫“构造函数”;因为构造函数会被系统自动调用,所以我们可以简单的理解成:构造函数的目的就是初始化类对象的数据成员。
//Time.h
class Time {
public:
int Hour;
int Minute;
int Second;
Time (int tmphour, int tmpminute, int tmpsecond);
};
//Time.cpp
Time::Time (int tmphour, int tmpminute, int tmpsecond)
{
Hour = tmphour;
Minute = tmpminute;
Second = tmpsecond;
}
- 构造函数没有返回值
- 不可以手工调用构造函数
- 正常情况下,构造函数应该被声明为public
- 构造函数中如果有多个参数,则我们创建对象的时候也要带上这些参数
//定义一个类对象
Time mytime = Time(3, 29, 23);
Time mytime(3, 29, 23);
Time mytime{
3, 29, 23);
Time mytime = Time{
3, 29, 23};
多个构造函数
提供多种初始化方法,但是参数表类型或者个数要有明显不同。
通过对象拷贝得到的新对象并没有调用传统意义上的构造函数而是调用了拷贝构造函数。
函数默认参数
- 函数的默认值只能放在函数声明中,除非该函数没有函数声明
- 在具有多个参数的函数中指定默认值时,默认参数都必须出现在不默认参数的右边
- 一旦某个参数指定了默认值,它右边的所有参数都必须制定默认值
隐式转换和explicit
在构造函数声明前添加explicit
可以强制性要求构造函数不能做隐式类型转换,只能用于初始化和显式类型转换。
构造函数初始化列表
定义构造函数时
Time::Time (int tmphour, int tmpminute, int tmpsecond)
:Hour(tmphour), Minute(tmpminute), Second(tmpsecond)
{
...;
}
03 inline、const、mutable、this、static
1 在类定义中实现成员函数inline
2 成员函数末尾的const
3 mutable
4 返回自身对象的引用,this
5 static成员
在类定义中实现成员函数inline
直接在.h头文件中类的定义中实现的成员函数,会被当作inline内联函数来处理。
成员函数末尾的const“常量成员函数”
在成员函数后增加一个const。不但要在成员函数声明中增加const,在函数定义时也要增加const。
作用:这个成员函数不会修改该对象里任何成员变量的值。
void classname::funcname (int valuelist) const;
结论:const成员函数,不管是const对象和非const对象都可以调用常量成员函数;而普通成员函数,不能用const对象调用。
mutable
不稳定,易改变的意思。为了图片const的限制
用mutable
修饰一个成员变量,一个成员变量一旦被mutable修饰了,就表示这个成员变量永远处于可以被修改状态。即便是在const结尾的成员函数中,也可以修改。
返回自身对象引用this
快捷键
ctrl + F3 + fn
查找文件中重名项
//Time.h
class Time {
int Hour;
Time& add_hour (int tmphour);
};
//Time.cpp
Time& Time::add_hour (int tmphour) //返回值是对象本身
{
Hour += tmphour; //this->Hour += tmphour;
return *this; //this就是指向对象本身的指针,*this就是对象本身
}
//project.cpp
#include "Time.h"
int main()
{
Time mytime;
mytime.add_hour(3);
}
在调用成员函数时,编译器负责把这个对象的地址(&mytime)传递给成员函数中一个隐藏的this形参。在系统角度看来,任何对类成员的直接访问都被看做是通过this做隐式调用的。
- this指针只能在成员函数中使用,全局函数、静态函数都不能使用this指针
- 在普通成员函数中,this是一个指向非const类型的const指针
(Time* const this)
指向不能变,值可以改变 - 在const成员函数中,this是一个指向const类型的const指针
(const Time* const this)
指向和值都不可以改变
static成员
属于整个类的成员变量,这种成员变量叫static成员变量(静态成员变量),同样也有静态成员函数。静态成员函数只能操作静态成员变量。
特点:不属于某个对象,属于整个类,一旦在某个对象中修改了这个成员变量的值,在其他对象中也会随之改变。
调用时类名::成员变量名``类名::成员函数名
//Time.h
class Time {
static int date; //还没有分配内存,不能初始化
};
//Time.cpp
int Time::date; //分配内存,不给初值默认为0,定义时不需要加static
04 类内初始化、默认构造函数、 =default
1 类相关非成员函数
2 类内初始化
3 const成员变量的初始化
4 默认构造函数
5 =default; ,=delete;
const成员变量的初始化
常量属性变量,需要在构造函数定义时使用初始化成员列表给出常量值。
默认构造函数
没有参数的构造函数称为默认构造函数。当没有构造函数时,进行“默认初始化”,编译器会生成一个“合成默认构造函数”。
使用多个构造函数时,一旦定义了一个构造函数系统就不会生成“默认构造函数”。
=default;
,=delete;
C++11引入
class Time {
public:
Time() = default; //编译器能够自动生成函数体(只能用于特殊的函数)
Time() = delete; //禁用某个函数
};
05 拷贝构造函数
如果一个类的构造函数的第一个参数是所属的类类型的引用。如果还有其他额外参数,那么这些额外的参数还都有默认值,则这个构造函数叫做拷贝构造函数。
class Time {
public:
Time (const Time& tmptime, int tmpvalue = 0);
};
Time::Time(const Time& tmptime