20170602
1 #include <iostream>
2 using namespace std;
3 class A {
4 public:
5 static void show(A *mythis) {//mythis是自己模拟this指针,做了编译器做的事情,本来静态方法不能访问非静态,原因是静态没有自己的this指针,我们加上以后,就可以了
6 mythis->play();
7 }
8 void play() {
9 cout << "this is play()" << endl;
10 }
11 };
12 int main() {
13 A a;
14 A::show(&a);
15 }
单例模式:整个程序中只有一个这个类型对象,比如任务管理器,不管你调几次,都只能出来 一个
多例:比如文件夹,可以点开N次
单例模式:共享池
静态成员变量
防止类外创建对象 私有构造 拷贝构造
静态函数 提供外界访问接口
饿汉式:立即会创建出对象
懒汉式:需要对象时才去创建
1 #include <iostream>
2 using namespace std;
3 class Singleton {
4 private: //私有化构造,拷贝构造,防止类外创建
5 Singleton() {};
6 Singleton(const Singleton& s) {};
7 static Singleton sig;//提供静态成员 类外初始化
8 public: //提供公开的得到对象的接口,使用类型就可以得到对象
9 static Singleton& getInstance() {
10 return sig;
11 }
12 };
13 Singleton Singleton::sig;//静态初始化,前面类型,后面变量名
14 int main() {
15 Singleton& sig1 = Singleton::getInstance();
16 Singleton& sig2 = Singleton::getInstance();
17 cout << &sig1 << endl;
18 cout << &sig2 << endl;
19 }
一、成员指针
struct Date {
int year;
int month;
int day;
};
1.1 指向成员变量的指针
int Date::*pmem; //成员指针,普通指针前面加类名::修饰。
pmen = &Date::year;//成员指针的赋值
Date date;
date.*pmem;//通过成员得到值
Date *date2 = new Date();
date2->*pmem;
1 #include <iostream>
2 using namespace std;
3 class Date {
4 public:
5 int year;
6 int month;
7 int day;
8 Date(int year = 0, int month = 0, int day = 0):year(year ),month(month),day(day) {
9
10 }
11 };
12
13 int main() {
14 //定义一个Date类型对应的成员指针
15 int Date::*pmem;
16 //赋值
17 pmem = &Date::year;
18 Date date(2017,5,31);
19 cout << date.*pmem << endl;
20 pmem = &Date::day;
21 cout << date.*pmem << endl;
22 }
本质:
成员变量指针的本质就是对象的地址偏移量
1.2 成员函数指针(代码区的函数的地址)
struct Date {
int year;
int month;
int day;
void showYear() {
cout << year << endl;
}
};
/*定义成员函数指针*/
void (Date::*pfun)();
/*赋值*/
pfun = &Date::showYear;
Date date;
//通过对象调用指针对应的函数
(date.*pfun)();
Date *date2 = new Date();
(date2->*pfun)();
1 #include <iostream>
2 using namespace std;
3 class Date {
4 public:
5 int year;
6 int month;
7 int day;
8 Date(int year = 0, int month = 0, int day = 0):year(y ear),month(month),day(day) {
9
10 }
11 void showYear() {
12 cout << year << endl;
13 }
14 void showMonth() {
15 cout << month << endl;
16 }
17 };
18
19 int main() {
20 void (Date::*pfun)();
21 pfun = &Date::showYear;
22 Date date(2017,5,31);
23 (date.*pfun)();
24 Date *date1 = new Date();
25 pfun = &Date::showMonth;
26 (date1->*pfun)();
27 }
二、运算符重载
2.1 本质:
就是函数的特殊表现形式
2.2 分数:
分数的特征
分子
分母
分数的功能
显示一个分数
分数的相加(全局函数两个分数相加)
1 #include <iostream>
2 using namespace std;
3 class Fraction {
4 public:
5 int x;
6 int y;
7 Fraction(int x = 0,int y = 1):x(x),y(y) {
8
9 }
10 void show() {
11 cout << x << "/" << y << endl;
12 }
13 };
14 /*设计一个函数实现两个分数相加*/
15 const Fraction add(const Fraction& f1,const Fraction& f2) {
16 return Fraction(f1.x*f2.y+f1.y*f2.x,f1.y*f2.y);
17 }
18 int main() {
19 Fraction fa(1,3);
20 fa.show();
21 Fraction fb(1,2);
22 Fraction fc = add(fa,fb);
23 fc.show();
24 }
L#R(#是操作符) 去L对象对应的类型中找一个成员函数operator#(R对象对应的类型par)
如果没有,就去全局区找一个全局函数operator#(L对象对应的类型par1,R对象对应的类型par2);
如果还没有发现就报错。
1 #include <iostream>
2 using namespace std;
3 class Fraction {
4 public:
5 int x;
6 int y;
7 Fraction(int x = 0,int y = 1):x(x),y(y) {
8
9 }
10 void show() {
11 cout << x << "/" << y << endl;
12 }
13 };
14 /*设计一个函数实现两个分数相加*/
15 const Fraction operator+(const Fraction& f1,const Fraction& f2) {
16 return Fraction(f1.x*f2.y+f1.y*f2.x,f1.y*f2.y); //Fraction();这是一个临时对象
17 }
18 int main() {
19 Fraction fa(1,3);
20 fa.show();
21 Fraction fb(1,2);
22 //Fraction fc = add(fa,fb);
23 Fraction fc = fa + fb;
24 fc.show();
25 }
成员形式的+号运算符
f1+f2 f1.operator+(f2)
const Fraction operator-(const Fraction f2) {
return Fraction((x*f2.y-f2.x*y),(y*f2.y));
}
2.3 设计一个类,包装一个整数
integer
成员变量
int data;
函数:
构造函数 负责赋值
提供两个整数相加相乘的运算符支持
判断两个整数是否相等(值相等)
显示这个整数的值
1 #include <iostream>
2 using namespace std;
3 class Integer {
4 public:
5 int data;
6 Integer(int data) {
7 this->data = data;
8 }
9 Integer operator+(Integer in) {
10 return Integer(data+in.data);
11 }
12 Integer operator*(Integer in) {
13 return Integer(data*in.data);
14 }
15 bool operator==(Integer in) {
16 return data==in.data;
17 }
18 void show() {
19 cout << data << endl;
20 }
21 };
22
23 int main() {
24 Integer a(10);
25 Integer b(20);
26 Integer e(20);
27 Integer c = a + b;
28 c.show();
29 Integer d = b * a;
30 d.show();
31 c = a * b;
32 c.show();
33 cout << (b == e) << endl;
34 }
2.4输入输出运算符的重载
ostream cout;
instream cin;
Integer c;
cout << c;
流对象不允许复制,不允许加const修饰,所以ostream必须引用
L#R(#是操作符) 去L对象对应的类型中找一个成员函数operator#(R对象对应的类型par)
如果没有,就去全局区找一个全局函数operator#(L对象对应的类型par1,R对象对应的类型par2);
如果还没有发现就报错。
cout.operator<<(Integer c)
ostream& operator<<(ostream& cout,Integer c)
返回值设计成ostream&
ostream& os 流不能复制,所以使用引用,流不能加const
const Integer& par2 const适应输出临时对象和const对象 引用减少拷贝
指针和引用 联系和区别
联系:引用是指针实现的 所以很多情况 指针可以用引用来代替函数的参数 函数的返回值
区别:1.引用必须初始化 指针不是必须的
2.引用一旦初始化 就不能改变绑定的对象 但是可以改变值
指针可以改变指向
3.指针是一个实体变量 大小4(32位系统)
引用是一个别名 大小和引用的对象有关
4.有指针的指针 没有引用的引用
5.有指针的引用 int*&
没有引用的指针 int&* //error
6.有指针的数组
没有引用类型的数组
int * data[10] = {&a, &b, &c}
int data[10] = {a,b,c} //a b c的值
7.有数组的引用
int data[3];
int (&rdata)[3];