目录
一.C语言和C++的区别
二.类的引入
三.类的定义
1.类的定义
2.类的成员方法的两种定义方式:
3.类的成员变量的定义
四.类的访问限定符及封装
1.访问限定符
五.面向对象的三大特征
1.面向对象的三大特征分别是什么
2.封装
六.类的作用域
七.创建类对象
1.类对象的实例化
2.类的大小
3.匿名对象
八.this指针
1.什么是this指针
2.关于this指针的两个问题。
九.C++类中的默认成员函数
1.类的6个默认成员函数
2.构造函数 (完成创建对象时的初始化工作) 是特殊的成员函数 构造函数可以私有化
a.特性:
b.类的构造函数的调用
3.析构函数(完成对象销毁时的清理工作) 先定义的后析构,后定义的先析构
a.特征:
b.不用显示调用析构函数的情况:
c.类对象的析构问题
4.拷贝构造函数(特殊的构造函数)是构造函数的重载。
a.特征:
5.运算符的重载
什么是运算符的重载
赋值运算符的重载
a. 赋值运算符重载格式
b. 赋值运算符只能重载成类的成员函数不能重载成全局函数
c. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。
注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。
前置++和后置++运算符的重载
a.前置++:
b.后置++:
流定向运算符的重载
6.取地址及const取地址操作符重载
十.const成员
十一.初始化列表
1.什么是初始化列表
2.为什么有了构造函数还需要初始化列表:
【注意】
十二.explicit关键字
十三.Static成员
1.概念
2.特性
十四.友元
1.什么是友元
2.友元函数
3.友元类
十五.内部类
1.概念:
2.特性:
一.C语言和C++的区别
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
二.类的引入
三.类的定义
1.类的定义
class className
{// 类体:由成员函数和成员变量组成}; // 一定要注意后面的分
2.类的成员方法的两种定义方式:
3.类的成员变量的定义
// 我们看看这个函数,是不是很僵硬?classDate
{
public:
void Init(int year){// 这里的year到底是成员变量,还是函数形参?year = year;}
private:int year;
};
// 所以一般都建议这样
class Date
{
public:void Init(int year){_year = year;}
private:int _year;
};
// 或者这样
class Date
{
public:void Init(int year){mYear = year;}
private:int mYear;
};
// 其他方式也可以的,主要看公司要求。一般都是加个前缀或者后缀标识区分就行。
四.类的访问限定符及封装
1.访问限定符
C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。
五.面向对象的三大特征
1.面向对象的三大特征分别是什么
2.封装
六.类的作用域
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{cout << _name << " "<< _gender << " " << _age << endl;
}
七.创建类对象
1.类对象的实例化
2.类的大小
3.匿名对象
八.this指针
1.什么是this指针
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout <<_year<< "-" <<_month << "-"<< _day <<endl;}
private:int _year; // 年int _month; // 月int _day; // 日int a;
};
int main()
{Date d1, d2;d1.Init(2022,1,11);、d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}
对于上面的代码的d1和d2两个对象在访问成员方法时,既然成员方法都在一个共享空间中,那么为什么两个对象的输出结果不同呢?
原因就是有 this指针的存在。
this指针是非静态成员函数默认定义的一个行参 Date&const this; 因为是const类型所以在函数中不可以改变this指针变量的内容。既然是一个形参那么出函数作用时就会销毁。this指针不可以在函数的形参和实参显示传递。
2.关于this指针的两个问题。
a.this指针是存放在栈空间的。
b.this可以为空吗?
可以为空
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:void PrintA() {cout<<_a<<endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->PrintA();return 0;
}
九.C++类中的默认成员函数
1.类的6个默认成员函数
2.构造函数 (完成创建对象时的初始化工作) 是特殊的成员函数 构造函数可以私有化
a.特性:
b.类的构造函数的调用
#include <iostream>using namespace std;class Date
{
public:Date(int year = 2023,int month = 12, int day = 31){_year = year ;_month = month;_day = day ;}
private:int _year;int _month;int _day;
};int main(void)
{Date d1;Date d2(2023, 12, 3);Date d3();return 0;
}
3.析构函数(完成对象销毁时的清理工作) 先定义的后析构,后定义的先析构
a.特征:
b.不用显示调用析构函数的情况:
c.类对象的析构问题
4.拷贝构造函数(特殊的构造函数)是构造函数的重载。
a.特征:
5.运算符的重载
什么是运算符的重载
赋值运算符的重载
a. 赋值运算符重载格式
b. 赋值运算符只能重载成类的成员函数不能重载成全局函数
c. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。
注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。
前置++和后置++运算符的重载
a.前置++:
b.后置++:
流定向运算符的重载
先看下面的代码:
#include <iostream>using namespace std;class Date
{
public:Date(int year = 2023,int month = 12, int day = 31){_year = year ;_month = month;_day = day ;}
private:int _year;int _month;int _day;
};int main(void)
{Date d1;Date d2(2023, 12, 3);cout << d2;return 0;
}
#include <iostream>using namespace std;class Date
{friend ostream& operator<< (ostream& cout, const Date& d);public:Date(int year = 2023,int month = 12, int day = 31){_year = year ;_month = month;_day = day ;}
private:int _year;int _month;int _day;
};int main(void)
{Date d1;Date d2(2023, 12, 3);cout << d1;return 0;
}ostream& operator<< (ostream& cout, const Date& d)
{cout << d._year << " " << d._month << " " << d._day << endl;return cout;
}
此时一定要使用ostream&因为ostream类有防止开拷贝的操作。
6.取地址及const取地址操作符重载
class Date
{
public :Date* operator&(){return this ;}const Date* operator&()const{return this ;}
private :int _year ; // 年int _month ; // 月int _day ; // 日
};
十.const成员
十一.初始化列表
1.什么是初始化列表
2.为什么有了构造函数还需要初始化列表:
【注意】
十二.explicit关键字
十三.Static成员
1.概念
class A
{
public:A() { ++_scount; }A(const A& t) { ++_scount; }~A() { --_scount; }static int GetACount() { return _scount; }
private:static int _scount;
};
int A::_scount = 0;
void TestA()
{cout << A::GetACount() << endl;A a1, a2;A a3(a1);cout << A::GetACount() << endl;
}
2.特性
十四.友元
1.什么是友元
2.友元函数
class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}// d1 << cout; -> d1.operator<<(&d1, cout); 不符合常规调用// 因为成员函数第一个参数一定是隐藏的this,所以d1必须放在<<的左侧ostream& operator<<(ostream& _cout){_cout << _year << "-" << _month << "-" << _day << endl;return _cout;}
private:int _year;int _month;int _day;
};
class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}
private:int _year;int _month;
int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << "-" << d._month << "-" << d._day;return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{_cin >> d._year;_cin >> d._month;_cin >> d._day;return _cin;
}
int main()
{Date d;cin >> d;cout << d << endl;return 0;
}
3.友元类
class Time
{friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成
员变量
public:Time(int hour = 0, int minute = 0, int second = 0): _hour(hour)
, _minute(minute), _second(second){}private:int _hour;int _minute;int _second;
};
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}void SetTimeOfDate(int hour, int minute, int second){// 直接访问时间类私有的成员变量_t._hour = hour;_t._minute = minute;_t._second = second;}private:int _year;int _month;int _day;Time _t;
};
十五.内部类
1.概念:
如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。
2.特性:
class A
{
private:
static int k;int h;
public:class B // B天生就是A的友元{public:void foo(const A& a){cout << k << endl;//OKcout << a.h << endl;//OK}};
};
int A::k = 1;
int main()
{A::B b;b.foo(A());return 0;
}