一文带你搞懂C++特殊成员

5. C++ 特殊成员

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
//重定义问题: 多次定义

小试牛刀

//自己总结特殊成员的特性,写出测试代码

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值