- 静态变量成员和静态变量函数
1.1静态成员变量
1.2编译阶段分配内存
1.3所有对象共享
1.4通过对象访问,通过类名访问
1.5有权限控制1.6静态成员函数
1.7可以访问静态成员变量,不可以访问普通成员变量
1.8普通成员函数都可以访问
1.9静态成员函数也有权限
1.10可以通过对象访问,也可以通过类名进行访问
-
单例模式案例-1
2.1 目的 为了让类中只有一个实例 ,实例也不需要自动的释放掉
2.2 将默认构造和拷贝构造私有化
2.3 内部维护一 对象指针
2.4私有化唯一指针
2.5 对外提供 getstance 方法来访问这个指针
2.6 保证类中只能实例化唯一一个对象 -
c++对象模型初探
3.1成员变量和成员属性是分开储存的
3.2空类大小 1
3.3只有非静态成员属性才属于对象身上
3.this指针的引用
4.1指针永远指向当前对象
4.2解决命名冲突
4.3*this 指向对象本体
4.4非静态成员函数才有this指针
- 空指针访问成员函数
class Person{};
Person *p=NULL;
5.1 如果成员函数没有用到this,那么空指针可以直接访问该成员函数
5.2如果成员函数用的this指针,就要注意空指针会挂掉,可以加if判断,如果this 为空NULL就return
4.常函数 常对象
7.1常函数 void func()const{} 常函数
7.2常函数 修饰是this指针 const type*const this
7.3常函数 不能修改this指针执行的值
7.4常对象 在对象前加入const修饰 const person p1;
7.5 常对象 不可以调用普通的成员函数但是可以调用常函数
-
友元
4.1全局函数做友元函数
4.1.1 全局函数 写到类中做声明 并且带上关键字
4.3 整个类做友元函数
4.2 类中成员函数做友元函数
4.2.1 friend void goodGay::visit(); -
加好运算符重载
5.1 如果想让自定义数据类型 进行+运算,那么就需要进行加号运算符重载
5.2 在成员函数 或者 全局函数里 重写一个+号运算符的函数
5.3 函数名 operator+(){}
5.4 运算符重载 也可以提供多个版本 -
左移运算符重载
6.1不要随意乱用符号重载
6.2内置数据类型 的运算符不可以重载
6.3 cout<<直接对Person自定义数据类型 进行输出
6.4 写到全局函数中 ostream & operator <<(ostream &cout ,Person &p1) { }
6.5 如果重载时候想访问p1 的私有成员,那么全局函数要做person的友元函数 -
前置 后置++运算符重载
7.1重载++运算符 operator()前置 operator(int)后置
7.2前置理念 先++后返回自身 后置理念先保存住原有值 内部++ 返回临时数据
7.3 联系 自己实现递减运算
此处,问题便出现了,代码: cout << ++myint <<endl; cout << myint << endl;
都能正常输出,但是加上:cout << myint++ << endl; 程序便报错。
- 解决方法
后面照着其他人的说法以及自己的测试,有两种修改方法: 1、在左移运算符的重载函数ostream&
operator<<(ostream& cout, MyInteger & myint)的第二个形参的前面加一个const变成:
ostream& operator<<(ostream& cout,const MyInteger & myint)
2、去掉ostream& operator<<(ostream& cout, MyInteger &
myint)的第二个形参前面的引用(&)符号。
- 本质解释 自己对此两种方法进行了思考,发现就是一个简单的常量引用的问题。
首先解释一下代码的执行顺序:不论<<++myint还是<<myint++,虽然其显示结果也和默认的递增符一样(前置先递增再输出,后置先输出再递增),但其本质上却都是先调用++重载,再调用<<重载(这一点可能与默认数据类型的前置后置执行顺序不一样)。
接下来解释左移重载写ostream &operator<<(ostream &cout , MyInteger
&myint)时,为什么前置递增(cout<<++myint)可以,而后置递增(cout<<myint++)会报错:
1、前置递增(++myint)时,重载返回的是对象myint,因此可以采用引用的方式传左移重载函数(<<)中进行重载;2、但后置递增(myint++)时,对象myint虽然加了1,但是返回的却是局部变量temp记录的值(常量)而不是对象myint,此时需要拿个变量去接收,但是左移重载函数并没有实现此功能,而是直接传进去引用了,相当于MyInteger
&myint = 10(直接给常量起别名myint,但这是非法的)。因此问题就变成了解决常量引用的问题。有两种修改方法来修改左移重载函数的函数头(回到了前面所学知识): 1、……,MyInteger
myint) 将常数0传入第二个形参,相当于MyInteger myint = 0(隐式转换法),即MyInteger
myint=MyInteger(0)(定义一个新形参对象myint,然后将0传进去) ; 2、……,const MyInteger
&myint) 将常数0传入第二个形参,相当于const MyInteger &myint =
0(开辟一片新内存,并用新的引用名myint操作这块内存;此时即使不知道此内存变量的具体名字,但是可以用此引用名对内存进行操作)
-
智能指针实现
8.1Person类有showAge 成员函数
8.2如果new出来的Person对象,就要让程序员自觉的去释放 delete
8.3有了智能指针,让智能指针托管这个Person对象,对象的释放就不用操心了,让智能指针管理
8.4为了让智能指针想普通的Person指针一样使用 就要重载 -> 和 -
赋值运算符重载
9.1系统默认给类提供 赋值运算符写法 是简单值拷贝
9.2导致如果类中有指向堆区的指针,就可能出现深浅拷贝的问题
9.3所以要重载 = 运算符
9.4如果想链式编程 return*this -
[]运算符重载
10.1返回数组索引的引用
10.2int & operator[](int index)
10.3return this->pAddress[index]