C++特殊类设计

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,表示该类不可被继承。

相关推荐

  1. C++特殊设计

    2023-12-11 01:08:01       50 阅读
  2. C++】特殊设计

    2023-12-11 01:08:01       44 阅读
  3. C++特殊设计

    2023-12-11 01:08:01       44 阅读
  4. C++特殊设计

    2023-12-11 01:08:01       46 阅读
  5. c++特殊设计

    2023-12-11 01:08:01       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-11 01:08:01       91 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-11 01:08:01       97 阅读
  3. 在Django里面运行非项目文件

    2023-12-11 01:08:01       78 阅读
  4. Python语言-面向对象

    2023-12-11 01:08:01       88 阅读

热门阅读

  1. 5.3 函数-递归与求阶乘

    2023-12-11 01:08:01       50 阅读
  2. 人工智能原理复习

    2023-12-11 01:08:01       48 阅读
  3. 第9节:Vue3 指令

    2023-12-11 01:08:01       57 阅读
  4. C#动态调用C++DLL中的函数

    2023-12-11 01:08:01       60 阅读
  5. ts中type和interface类型声明的区别

    2023-12-11 01:08:01       64 阅读
  6. harmonyOS学习笔记之状态修饰器@state,@prop,@link

    2023-12-11 01:08:01       54 阅读
  7. 排列游戏 --- 动态规划 --- 题解

    2023-12-11 01:08:01       64 阅读