C++:特殊类设计和四种类型转换

2024-06-04 2303阅读

C++:特殊类设计和四种类型转换 第1张

一、特殊类设计

1.1 不能被拷贝的类

          拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。

C++98:

1、将拷贝构造函数与赋值运算符重载只声明不定义。(防自己人)

        不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写反而还简单,而且如果定义了就可能导致成员函数进行内部拷贝了。

2、并且将其访问权限设置为私有即可。(防外人)

        如果只声明没有设置成private,用户自己如果在类外定义了,就可以不能禁止拷贝了

class CopyBan
{
// ...
private:
CopyBan(const CopyBan& c);
CopyBan& operator=(const CopyBan& c);
//...
};

C++11:

       C++11扩展delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟=delete,表示让编译器删除掉该默认成员函数。

class CopyBan
{
// ...
CopyBan(const CopyBan& c)=delete;
CopyBan& operator=(const CopyBan& c)=delete;
//...
};

1.2 只能在堆上创建对象的类

思路1:

1. 将类的构造函数私有,拷贝构造声明成私有(可以直接delete掉)。防止别人调用拷贝在栈上生成对象。

      注意:拷贝构造可以直接delete掉,但是构造函数不行!!因为我们还需要利用构造函数在堆上创建对象。
2. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建。

     注意:这里涉及到的是先有鸡还是先有蛋的问题,因为如果不去创建这个对象就没有办法去调用他的构造函数,但是没有调用构造函数就没有办法创建对象。所以这里必须通过静态成员函数的返回值去构造堆对象。

class HeapOnly
{
public:
	static HeapOnly* CreateObject()
	{
		return new HeapOnly;
	}
private:
	HeapOnly(){};
	HeapOnly(const HeapOnly&) = delete;
};
int main()
{
	HeapOnly*p = HeapOnly::CreateObject();
	return 0;
}

C++:特殊类设计和四种类型转换 第2张

思路2:

1、相比较于上一种思路把构造函数私有、拷贝构造delete,也可以选择将析构函数给设成私有。

      析构函数设置成私有同样会导致对象无法在栈上进行创建。因为自定义类型在栈帧中销毁的时候会去自动调用他的析构函数,但是因为调不到所以会报错。

2、封装一个destory的成员函数,这样我们可以手动释放堆空间的资源。

      在堆上创建对象是用指针去接受,所以并不影响,但是内存需要我们去手动释放,因此我们需要封装destory的成员函数去调用delete,这样delete可以对应调用到析构函数。 这里有两个方案:一种是设置能静态成员函数(类域调用),一种是设置成普通成员函数(对象自己调用)。

class HeapOnly
{
public:
	//方案1 
	static void Destroy(HeapOnly* hp)
	{
		delete hp;
	}
	//方案2
	void Destroy()
	{
		delete this;
	}
private:
	~HeapOnly() {};
};
int main()
{
	//HeapOnly H; 调不到析构函数,无法创建
	//静态成员函数释放
	HeapOnly* ptr = new HeapOnly;
	HeapOnly::Destroy(ptr);
	//普通成员函数释放
	HeapOnly* ptr2 = new HeapOnly;
	ptr2->Destroy();
	return 0;
}

C++:特殊类设计和四种类型转换 第3张

1.3 只能在栈上创建对象的类

1、new和delete是全局的运算符重载函数,因此我们只要将这两个给禁用掉,就不会在堆上创建对象。

      需了解具体声明:void* operator new(size_t size) 和 void operator delete(void* p) 。实现类专属的operator new和delete 这样new这个类对象时,operator new就会调用这个,不会调全局的。

	class StackOnly
	{
	public:
		static StackOnly CreateObj()
		{
			return StackOnly();
		}
		// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
		// StackOnly obj = StackOnly::CreateObj();
		// StackOnly* ptr3 = new StackOnly(obj);
		void* operator new(size_t size) = delete;
		void operator delete(void* p) = delete;
	private:
		int _a;
	};
	int main()
	{
	    StackOnly obj;
		//StackOnly* s = new StackOnly;
	}

C++:特殊类设计和四种类型转换 第4张

但是没有办法去禁用C语言的相关函数。 

1.4 不能被继承的类

C++98:

构造函数私有化,这样子类调用不到父类的构造函数,无法实现继承

class NonInherit
{
public:
static NonInherit GetInstance()
{
return NonInherit();
}
private:
NonInherit()
{}
};

C++11:

直接用final关键字,可以使得该类无法被继承

class A final
{
// ....
};

1.5 控制可创建对象数量的类

设置一个静态int变量count,每创建一个对象就--count

class singleclass
{
public:
	static singleclass* getsingleclass()
	{
		if (count > 0)
		{
			count--;
			return new singleclass();
		}
		else
		{
			cout 

    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]