C++特殊类的设计

开头整体说明一下,要求特殊类不能实现的功能,一种方式是将这种方式私有化,另一种方式是用特殊的关键字控制

目录

一、请设计一个类,不能被拷贝

第一种:私有化

第二种:禁用delete

二、请设计一个类,只能在堆上创建对象

三、请设计一个类,只能在栈上创建对象

四、请设计一个类,不能被继承

第一种:私有化

第二种:final关键字

五、请设计一个类,只能创建一个对象(单例模式)

饿汉模式:

懒汉模式:

不支持线程安全:

支持线程安全:


一、请设计一个类,不能被拷贝

类的拷贝只会在两个场景中出现:一个是构造的时候---拷贝构造,另一个则是赋值的时候。所以只需要将这两种函数禁止访问即可。

第一种:私有化

class A
{
public:
	A()
	{}
private:
	A(const A& x)
	{}
	A operator=(const A& x)
	{}
};

第二种:禁用delete

class A
{
public:
	A()
	{}
private:
	A(const A& x) = delete;
	A operator=(const A& x) = delete;
};

二、请设计一个类,只能在堆上创建对象

如果想要用户只能在堆上创建类的话,那就不能让用户直接访问到构造函数和赋值拷贝,因为这种默认的方式都是在栈上创建类对象的

class A
{
public:
	static A* create()
	{
		A* p = new A;
		return p;
	}
	~A()
	{
		cout << "~A" << endl;
	}
private:
	A()
	{
		cout << "A()" << endl;
	}
	A(const A& x) {}
	A operator=(const A& x) {}
};
int main()
{
	A::create();
	return 0;
}

三、请设计一个类,只能在栈上创建对象

因为只能在栈上创建,所以只需要将new和delete禁用或者私有化即可

class A
{
private:
	//void* operator new(size_t x) {}
	//void operator delete(void* p) {}
public:
	void* operator new(size_t x) = delete;
	void operator delete(void* p) = delete;
};

四、请设计一个类,不能被继承

如果一个类不能被继承,可以用final关键字进行修饰这个类;也可以将该类的构造函数进行私有化,在派生类构造中,调不到基类的构造,间接的禁止该类被继承。

第一种:私有化

class A
{
public:
	~A()
	{}
private:
	A()
	{}
};

第二种:final关键字

class A final
{
public:
	~A()
	{}
private:
	A()
	{}
};

五、请设计一个类,只能创建一个对象(单例模式)

单例模式:就是只能创建一个对象。

单例模式分为两种:饿汉模式,懒汉模式。

饿汉模式:

不管将来用不用,程序启动时就创建一个唯一的实力对象。

饿汉模式:优点:线程安全,性能高;缺点:容易导致资源浪费,不可延时加载

//饿汉模式
class A
{
private:
	//声明一个静态的对象
	static A a;
	//构造函数私有化
	A()
	{
		cout << "A()" << endl;
	}
public:
	//返回实例
	static A* Getinstance1()
	{
		return &a;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
	//禁用拷贝构造和赋值运算符重载
	A(const A& x) = delete;
	A operator=(const A& x) = delete;
};
//类内声明,类外定义
A A::a;

懒汉模式:

延迟加载吗,当需要用到时,才创建对象。

懒汉模式:优点:资源利用率高,可延时加载;缺点:线程不安全,性能差(每次调用时,需要同步检查)

不支持线程安全:
//懒汉模式
class A
{
private:
	//声明一个静态对象
	static A* a;
	//构造函数私有化
	A()
	{}
public:
	static A* Geta()
	{
		if (a == nullptr)
		{
			a = new A();
			return a;
		}
	}
	//禁用拷贝构造和赋值运算符重载
	A(const A&) = delete;
	A& operator=(const A&) = delete;
};
//类内声明,类外定义
A* A::a = nullptr;

int main()
{
	A*p=A::Geta();
	return 0;
}
支持线程安全:
//懒汉模式
class A
{
private:
	//声明一个静态对象
	static A* a;
	static std::mutex mtx;
	//构造函数私有化
	A() {}
public:
	static A* Geta()
	{
		if (a == nullptr)
		{
			//自动加锁解锁,保证开辟空间的操作是原子的
			std::lock_guard<std::mutex> lg(mtx);
			a = new A();
		}
		return a;
	}
	//禁用拷贝构造和赋值运算符重载
	A(const A&) = delete;
	A& operator=(const A&) = delete;
};
//类内声明,类外定义
std::mutex A::mtx;
A* A::a = nullptr;

int main()
{
	A*p=A::Geta();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值