C++特殊类设计

2023-12-14 19:40:59

1.设计不能被拷贝的类

解析:拷贝只会放生在两个场景中

  1. 拷贝构造函数
  2. 赋值运算符重载

因此想要让一个类禁止拷贝, 就需让该类不能调用“拷贝构造函数”以及“赋值运算符重载”,而C++11提供的delete重载关键字可以让这件事情变得更加简单。

1.1.C++98做法

class CopyBan
{
public:
	CopyBan()
		: _c(1) 
	{}

private:
	//拷贝构造私有化
	CopyBan(const CopyBan&);
	//赋值重载私有化
	CopyBan& operator=(const CopyBan&);

private:
	int _c;
};

int main()
{
	CopyBan c;
	//CopyBan copy(c);//禁用了

	return 0;
}

1.2.C++11做法

class CopyBan
{
public:
	CopyBan()
		: _c(1) 
	{}
	//拷贝构造私有化
	CopyBan(const CopyBan&) = delete;
	//赋值重载私有化
	CopyBan& operator=(const CopyBan&) = delete;

private:
	int _c;
};

int main()
{
	CopyBan c;
	//CopyBan copy(c);//禁用了

	return 0;
}

2.设计在堆上创建的类

2.1.析构私有

解析:一个在栈上的对象如果没有办法调用析构,就没有办法被创建,因为编译器认为没有析构,禁止直接创建对象,这种情况就只能使用new创建对象,并且提供一个用于释放的接口。

class HeapOnly
{
public:
    static void Destroy_1(HeapOnly* ptr)
    {
        delete ptr;
    }
    //or
    void Destroy_2()
    {
        delete this;
    }

private:
    ~HeapOnly() {}
};

int main()
{
    //HeapOnly h1;//禁用

    HeapOnly* ph1 = new HeapOnly;
    HeapOnly::Destroy_1(ph1);

    HeapOnly* ph2 = new HeapOnly;
    ph2->Destroy_2();

    //HeapOnly h2(*ph1);//禁用

    return 0;
}

2.2.构造私有

解析:如果一个类的构造被私有了,那么就无法直接调用,包括new也无法调用,然后我们提供给用户一个接口,在类的内部new返回类指针给用户,交给用户释放即可。

就是需要注意,还需要将拷贝构造私有化,避免用户使用接口后,解引用进行拷贝。

class HeapOnly
{
public:
    static HeapOnly* CreateObject()//这里必须是 static 静态成员函数
    {
        return new HeapOnly;
    }

private:
    HeapOnly() {}
    HeapOnly(const HeapOnly&);
};

int main()
{
    //HeapOnly h1;//禁用
    HeapOnly* ph = HeapOnly::CreateObject();//如果不是静态就需要创建对象来调用 CreateObject(),但我们已经没有办法产生对象了
    //HeapOnly h2(*ph);//禁用
    return 0;
}

3.设计在栈上创建的类

解析:需要删除operator new()才能彻底解决问题,注意不能私有构造函数!

class StackOnly
{
public:
	static StackOnly CreateObj()
	{
		return StackOnly();
	}

	//禁掉 operator new() 可以把用 new 调用拷贝构造申请对象给禁掉
	void* operator new(size_t size) = delete;
	void operator delete(void* p) = delete;

private:
	StackOnly()//实际上删除了 operator new() 就无需将构造函数私有化了,上述的 CreateObj() 也可以一起不要了
		: _a(0)
	{}

	//不可私有拷贝构造
	//StackOnly(StackOnly& s)
	//	: _a(0)
	//{}

private:
	int _a;
};

int main()
{
	StackOnly obj = StackOnly::CreateObj();
	//StackOnly* ptr1 = new StackOnly();//禁用
	//StackOnly* ptr2 = new StackOnly(obj);//禁用,这个不能私有拷贝构造,只能删除 new 的底层调用 operator new,否则就无法返回 CreateObj() 的结果
	//delete& obj;//禁用

	return 0;
}

4.设计无法被继承的类

4.1.C++98做法

父类的构造函数被私有化就不会被子类继承。

4.2.C++11做法

使用关键字final,表示该类不可被继承。

文章来源:https://blog.csdn.net/m0_73168361/article/details/134898287
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。