C++特殊成员
const成员
- const修饰的数据成员
- 初始化必须采用初始化参数列表
- 不能被修改
- 构造函数必须要初始化常数据成员
- const修饰的成员函数
- 写法上要注意: const修饰是写在函数后面
- const成员函数不能修改任何的数据成员
- 如果实在是要在常成员函数中修改该数据,用mutable修饰数据成员即可
- 常成员函数可以普通函数同时存在
- const对象
- const修饰的对象
- 常对象只能调用常成员函数
#include <iostream> using namespace std; class MM { public: MM(int age) :name("小芳"), num(4323) { this->age = age; } MM(string name, int age, int num) :name(name), age(age), num(num) { } //MM() {} 常数据必须要初始化,错误 //MM() = default; //正确,可以构造无参对象 void print() { age = 18; //num = 11; //不能修改常数据成员 cout << this->name << " " << this->num << " " << this->age << endl; cout << "普通函数" << endl; } //常成员函数: const写在函数后面 void print() const { cout << this->name << " " << this->num << " " << this->age << endl; cout << "常成员函数" << endl; } void printData() const { //age = 23; //常成员函数,不能修改数据成员 cout << this->name << this->num << this->age << endl; } void test() {} protected: //常数据成员 const string name; const int num; int age; //mutable 可修改的意思 }; int main() { MM mm("小丽", 18, 1001); //如果普通函数和常成员函数同名 mm.print(); //普通对象优先调用普通函数 const MM object(18); object.print(); //常对象只能调用常成员函数 object.printData(); //object.test(); //错误,常对象只能调用常成员函数 return 0; }
static成员
static成员不属于某一个单独对象,是属于类的,通俗一点讲,是所有对象的共享的,static成员依然受权限
satic成员他的访问可以不需要对象(用类名限定的方式去访问)
- static数据成员
- 初始化必须在类外初始化
- 类实现的时候不需要用static修饰了
- static成员函数
- static写在修饰函数的前面
- 类外实现也不需要static修饰
- 静态函数中没有this指针
- 静态成员函数的访问问题
- 静态成员函数访问静态成员 是可以直接访问
- 静态成员函数访问非静态数据成员,必须通过指定对象的方式
- 静态成员函数传参
- 在静态成员函数定义对象去访问
#include <iostream> #include <string> using namespace std; class User { public: User(string name = "默认") { this->count++; //类中访问 this->m_count++; } void print() { cout << name << " " << count << endl; } //void test() {} 不能和普通函数形参重载效果,会造成重定义问题 public: static void test(); static void testData(User& object); private: string name; public: static int count; int m_count = 0; }; //必须在类外面做初始化,不需要static修饰了 int User::count = 0; void User::test() { cout << "count:" << count << endl; //cout << "m_count:" << m_count << endl; //静态成员函数中不能直接调用非静态成员 cout << "静态函数" << endl; } void User::testData(User& object) { cout << object.m_count << endl; //传参 User mm; cout << mm.m_count << endl; //创建对象 } int main() { cout << User::count << endl; //static 成员访问不需要对象 User object[3]; cout << User::count << endl; User mm; cout << mm.count << endl; cout << User::count << endl; //可以用类名访问,前提是权限没问题 cout << mm.m_count << endl; //不能用类名 User::test(); //因为存在这种调用,所以静态成员函数中不能存在this指针 mm.test(); return 0; }
单例设计模式
什么是设计模式
- 模式: 套路 ---> 写代码的习惯
- 设计模式:前人总结的具有代表的套路
(官方说法:又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结) - 设计模式究极目标: 通过增加代码的形式去减少因为变化而要修改原代码的问题(维护问题)
单例设计模式
什么是单例设计模式
保证整个类的使用只有一个对象
- 多线程网络资源初始化
- 回收站机制
- 任务管理器
- 日志管理
如何实现单例设计模式
- 构造函数私有化
- 提供一个全局的静态方法,访问唯一对象
- 类中定义一个而静态指针,指向唯一对象
单例设计模式实现代码
懒汉式
在类中创建一个对象(只有用的才去创建)
:线程不安全
/* - 构造函数私有化 - 提供一个全局的静态方法,访问唯一对象 - 类中定义一个而静态指针,指向唯一对象 */ #include <iostream> using namespace std; class SingleTon { public: //类中定义一个而静态指针,指向唯一对象 static SingleTon* m_singleTon; //提供一个全局的静态方法,访问唯一对象 static SingleTon* GetInstance() { if (m_singleTon == nullptr) { m_singleTon = new SingleTon; } return m_singleTon; } private: SingleTon() { cout << "构造对象...." << endl; m_singleTon = nullptr; } }; SingleTon* SingleTon::m_singleTon=nullptr; int main() { SingleTon* p1 = SingleTon::GetInstance(); cout << "p1:" << p1 << endl; SingleTon* p2 = SingleTon::GetInstance(); cout << "p2:" << p2 << endl; return 0; }
饿汉式
全局创建的一个对象(饥不择食,用不用都去创建)
:线程安全
/* - 构造函数私有化 - 提供一个全局的静态方法,访问唯一对象 - 类中定义一个而静态指针,指向唯一对象 */ #include <iostream> using namespace std; class SingleTon { public: //类中定义一个而静态指针,指向唯一对象 static SingleTon* m_singleTon; //提供一个全局的静态方法,访问唯一对象 static SingleTon* GetInstance() { return m_singleTon; } private: SingleTon() { cout << "构造对象...." << endl; } }; SingleTon* SingleTon::m_singleTon=new SingleTon; int main() { SingleTon* p1 = SingleTon::GetInstance(); cout << "p1:" << p1 << endl; SingleTon* p2 = SingleTon::GetInstance(); cout << "p2:" << p2 << endl; return 0; }
单例设计优缺点
- 优点
- 内存中只有一个对象,节省内存空间
- 避免频繁创建和销毁对象,提高性能
- 避免对共享的资源的多重占用,简化访问
- 缺点
- 不适用变化频繁的对象
- 长时间不使用对象,导致系统回收掉
C++多文件写法
- 一个类一个模块
- 声明写在.h
- 实现写在.cpp
- 声明和试下写在一起 .hpp
- 头文件包含尽量在.cpp完成
- 设计项目时候,头文件形成交叉包含,说明思想有问题,自己重新设计代码
- 不要为了拆分而拆分
- 静态数据成员多文件写法
error LNK2019: 无法解析的外部符号 "public: __cdecl MM::~MM(void)" (??1MM@@QEAA@XZ),函数 main 中引用了该符号 //1.无法解析: 没有实现这个函数 //2. "public: __cdecl MM::~MM(void)" (??1MM@@QEAA@XZ) //2.1 public:权限 //2.2 __cdecl:调用准备 //2.2 MM::~MM(void): 函数名 error C2572: “MM::initData”: 重定义默认参数 : 参数 1 //重定义问题: 多次定义
小试牛刀
//自己总结特殊成员的特性,写出测试代码交上来