如何实现一个只能在栈上或者堆上生成对象的类?

什么才算是在栈上定义的对象?什么是在堆上定义的对象?

  • 堆上:即存放的是由new创建的对象和数组,即动态申请的内存都放在堆内存

  • 栈上:存放的是用来一些基本类型的变量和对象的引用变量

  • 堆就相当于在家自己做饭,吃饭苦逼的还要刷碗,呜呜呜~

  • 栈就相当于去饭店吃饭,只管吃,不管其他,生活美滋滋~

【分析】也就是说我们可以将题目理解为:

  • 只能在堆上--->只能使用new创建对象

  • 只能在栈上--->不能使用new来创建对象

  • 而我们知道在不管在哪创建对象我们都需要调用构造函数,既然要有所限制,那么我们首先想到的就是将构造函数声明为私有的,然后具体情况再另行分析,到底行不行,试过就知道了

那具体怎么实现呢?

(一)只能在栈上创建对象

(方案一)我们先把构造函数定义为私有的,然后在类内再定义一个函数来访问构造函数

class B
{
public:
	static B getB()
	{
		return B();
	}
private:
	B(int b = 0)
		:_b(b)
	{}
private:
	int _b;
};
B::B(const B& b)
{
	B* p = new B;//但是不能防止这样的事情发生!
}
int main()
{
	B::getB();//在栈上生成对象
	//B* pb = new B;//不可访问
	system("pause");
	return 0;
}

我们看到还是有点问题,那怎么来防止这样的情况发生呢?网上有人给出了这样的答案

(方案二)将operator new 定义为私有的

方法二、将operator new定义为私有的,new的底层就是operator new
class B
{
private:
	void* operator new(size_t size);
	void operator delete(void*p);
private:
	int _b;
};
int main()
{
	B b;//在栈上生成对象
	//B* pb = new B;//不可访问
	system("pause");
	return 0;
}

(二)定义一个只能在堆上生成对象的类

(方案一)还是将构造函数定义为私有的

class B
{
public:
	static B* GetB()
	{
		return new B();
	}
private:
	B(int b = 0)
		:_b(b)
	{}
private:
	int _b;
};
int main()
{
	B::GetB();
	//B(b);//如此定义,虽然可以防止这样的
	B*p = B::GetB();
	/*B b(*p);
	system("pause");*///但是这样不能防止
	return 0;
}

(方案二)我们可以将拷贝构造和赋值运算符重载都定义为私有的,这样就能防止上述情况了

class B
{
public:
	static B* GetB()
	{
		return new B();
	}
private:
	B(int b = 0)
		:_b(b)
	{}
	B(const B& b);
	B& operator=(const B&b);
private:
	int _b;
};
int main()
{
	B::GetB();
	//B(b);//如此定义,虽然可以防止这样
	B*p = B::GetB();
/*	B b(*p);
	system("pause");*///这样可以防止
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值