C++特殊类的设计: 只能在堆/栈上创建对象, 不能被继承的类

我们可能有时候会被问到C++的一写特殊类, 只能在堆上创建对象, 只能在栈上创建对象, 或者不能被继承的类.
那么怎么设计呢? 让我们一起来学习~


只能在堆上创建对象的类

只能在堆上申请空间, 也就是只能动态申请
不能在栈上创建对象, 所以我们首先就不能让构造函数随便被调用
首先要将构造函数私有化

构造函数私有化之后, 也无法在堆上创建对象
所以我们要提供一个接口供外部调用, 通过这个接口创建对象
因为构造函数已经私有化, 所以现在已经无法实例化对象, 也就无法调用接口, 但是静态成员可以直接通过类名访问
所以这里提供一个静态的公有接口, 通过类名直接在堆上创建对象
这里一定是返回地址

虽然构造函数私有化了, 但是还有拷贝构造
我可以先在堆上创建对象, 然后调用拷贝构造依然可以创建栈上的对象
所以这里还需要进行防拷贝的操作, 有两种方法
1. 只声明不实现
2. 直接定义成delete函数
建议使用第二种, 比较彻底 0.0

具体代码如下:

//只能在堆上创建的对象
class HeapOnly {
public:
	//静态公有的方法,创建对象
	static HeapOnly* getobj() {
		//堆上创建对象
		return new HeapOnly;
	}
private:
	//构造函数私有化
	HeapOnly() { }

	//防拷贝: 
	//1. 声明不实现
	HeapOnly(const HeapOnly& ho);
	//2. 直接定义成delete函数
	HeapOnly(const HeapOnly& ho) = delete;
};


void test() {
	//栈上的对象:自动调用公有的无参默认构造
	//HeapOnly ho;
	
	//堆上的对象
	HeapOnly* ptr = HeapOnly::getobj();
}


只能在栈上创建对象的类

第一种方法

这种方法和上面的方法一样
构造函数私有化 + 静态的公有接口
这是就是返回值即可, 也不用防拷贝, 毕竟在栈上创建

具体代码如下:

//只能在栈上创建的对象
class StackOnly {
public:
	//静态公有方法, 在栈上创建对象
	static StackOnly getobj() {
		StackOnly so;
		return so;
	}

	//拷贝构造不用管, 本来就在栈上

private:
	//构造函数私有化
	StackOnly() {}
};

第二种方法

既然不让在堆上申请空间, 还是自定义类型 (通过调用operator new来申请空间)
那我直接把operator new和operator delete禁掉不就行了

//第二种方法
class StackOnly2 {
public:
	//重定义operator new/delete, 定义成删除函数
	void* operator new(size_t n) = delete;
	void operator delete(void* ptr) = delete;
};

不能被继承的类

这个就非常简单了
第一种方法是直接把父类声明为final类,禁止继承
第二种是把父类构造私有化, 子类无法调用父类构造也就无法实例化对象, 继承了也没用

//设计一个不能被继承的类
//1. 声明为final类
class Base1 final {

};

//2. 父类构造私有化 (继承后子类无法实例化对象)
class Base {
private:
	Base() 
	{}
};
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殇&璃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值