c++特殊成员 / 单例设计模式 / 如何写多文件

c++特殊成员


const

①const修饰的数据成员

  • 写法上在变量类型前面加const
  • 构造函数必须要初始化常数据成员
  • 初始化必须采用初始化参数列表
  • 不能被修改
#include<iostream>
#include<string>
using namespace std;

class Boy
{
public:
	Boy(string name, int age, const int id) :name(name), age(age), id(id)
	{
	}
	//Boy(){}     初始化必须采用初始化参数列表
	//Boy() = default;     可以这样构造无参对象
	void print()
	{
		//id++;   数据成员不能被修改
		cout << this->name << " " << this->age << " " << this->id << endl;
	}
protected:
	string name;
	int age;
	const int id;
};


int main()
{
	Boy boy("九梦", 20, 111);
	boy.print ();
	return 0;
}

②const修饰的成员函数

  • 写法上要注意: const修饰是写在函数后面
  • const成员函数不能修改任何的数据成员
  • 如果实在是要在常成员函数中修改该数据,用mutable修饰数据成员即可(知道就行,一般不用)
  • 常成员函数可以和普通函数同时存在

③const修饰的成员

  • const修饰的对象
  • 常对象只能调用常成员函数
#include<iostream>
#include<string>
using namespace std;

class Boy
{
public:
	Boy(string name, int age, const int id) :name(name), age(age), id(id)
	{
	}
	//普通成员函数
	void print()
	{
		cout << "普通成员函数" << endl;
		cout << this->name << " " << this->age << " " << this->id << endl;
	}
	//常成员函数: const写在函数后面
	void print()const
	{
		//age = 23;      //常成员函数,不能修改数据成员
		cout << "常成员函数" << endl;
		cout << this->name << " " << this->age << " " << this->id << endl;
	}

protected:
	string name;
	int age;
	const int id;
};


int main()
{
	Boy boy("九梦", 20, 111);
	boy.print ();			//普通对象优先调用普通函数
	const Boy boy1("莫", 21, 110);
	boy1.print();			//常对象只能调用常成员函数
	return 0;
}

在这里插入图片描述

static

static成员不属于某一个单独对象,是属于类的,通俗一点讲,是所有对象的共享的,static成员依然受权限

static成员的访问不需要对象(用类名限定的方式去访问)
①static数据成员

  • 初始化必须在类外初始化
  • 类实现的时候不需要用static修饰了
#include<iostream>
#include<string>
using namespace std;

class Student
{
public:
	Student(string name) :name(name)
	{
	}
	void print()
	{
		count++;
		cout << name << " " << count << endl;
	}
private:
	string name;
	static int count;
};
int Student::count = 0;		//类外初始化,不需要static修饰

int main()
{
	Student studentone("莫");
	studentone.print();
	Student studenttwo("九梦");
	studenttwo.print();
	return 0;
}

② static成员函数

  • static写在修饰函数的前面
  • 类外实现是不需要static修饰的
  • 静态函数中没有this指针
  • 静态成员函数的访问问题
    • 静态成员函数访问静态成员 是可以直接访问
    • 静态成员函数访问非静态数据成员,必须通过指定对象的方式
      • 静态成员函数传参
      • 在静态成员函数定义对象去访问
#include<iostream>
#include<string>
using namespace std;

class Student
{
public:
	Student(string name) :name(name)
	{
	}
	void print()
	{
		count++;
		cout << name << " " << count << endl;
	}
	//非静态成员可以直接调用静态成员
	void printcount()
	{
		cout << count << endl;
	}
	//静态成员函数可以调用静态成员
	static int my_count() 
	{ 
		return count++; 
	}
	//静态成员函数不能直接调用非静态成员,要加特定对象,可以直接传参或创建对象
	//static void my_name() { name = "小明"; }
	static void my_name(Student& student) 
	{ 
		student.name = "小明"; 
	}
private:
	string name;
	static int count;
};
int Student::count = 0;		//类外初始化

int main()
{
	cout<<Student::my_count()<<endl;			//static 成员访问不需要对象
	Student studentone("莫");
	studentone.print();
	studentone.printcount();
	Student::my_count();
	Student studenttwo("九梦");
	studenttwo.print();
	return 0;
}

单例设计模式

👀 什么是设计模式

①首先我们先说说模式,模式就是一种套路,是一种写代码的习惯,
②那么设计模式就是前人总结的具有代表性的代码设计套路
(设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结)
🎯设计模式究极目标: 通过增加代码的形式去减少因为变化而要修改原代码的问题(维护问题)

单例设计模式

什么是单例设计模式

🎯保证整个类的使用只有一个对象,例如:

  • 多线程网络资源初始化
  • 回收站机制
  • 任务管理器
  • 日志管理
如何实现单例设计模式
  • 构造函数私有化
  • 提供一个全局的静态方法,访问唯一对象
  • 类中定义一个而静态指针,指向唯一对象

单例设计模式实现

懒汉式

在类中创建一个对象(只有用的才去创建)
:线程不安全

#include<iostream>
using namespace std;

class Singleton
{
public:
	//类中定义一个而静态指针,指向唯一对象
	static Singleton* m_singleton;
	//提供一个全局的静态方法,访问唯一对象
	static Singleton* GetSingleton()
	{
		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::GetSingleton();
	cout << "p1:" << p1 << endl;
	Singleton* p2 = Singleton::GetSingleton();
	cout << "p2:" << p2 << endl;
	return 0;
}

在这里插入图片描述

饿汉式

全局创建的一个对象(饥不择食,用不用都去创建)
:线程安全

#include<iostream>
using namespace std;

class Singleton
{
public:
	//类中定义一个而静态指针,指向唯一对象
	static Singleton* m_singleton;
	//提供一个全局的静态方法,访问唯一对象
	static Singleton* GetSingleton()
	{
		return m_singleton;
	}
private:
	Singleton()
	{
		cout << "构造对象" << endl;
		m_singleton = nullptr;
	}
};
Singleton* Singleton::m_singleton = new Singleton;
int main()
{
	Singleton* p1 = Singleton::GetSingleton();
	cout << "p1:" << p1 << endl;
	Singleton* p2 = Singleton::GetSingleton();
	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
//重定义问题: 多次定义
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值