0
点赞
收藏
分享

微信扫一扫

SQL注入之查询方式及报错盲注

飞鸟不急 2024-08-15 阅读 26

文章目录


一、设计一个不允许拷贝的类

1、方法一:将拷贝构造和赋值重载声明不定义并且放到私有域。
解释:

2、方法二:直接将拷贝构造和赋值重载删除。

3、演示

//防拷贝 - 不允许拷贝
class Base1
{
public:
	Base1(int a = 10):_a(a)
	{}

private:
	//c++98做法 -- 将函数声明不定义加不声明
	//Base1(const Base& b);
	//Base1& operator=(const Base& b);
	
	//c++11及以后做法 -- 将函数删除
	Base1(const Base1& b) = delete;
	Base1& operator=(const Base1& b) = delete;
	int _a = 0;
};

void test01()
{
	Base1 b1;
	//会报错
	//Base1 b2(b1);
}

在这里插入图片描述

二、设计一个只能在堆上实例对象的类

1、方法:将构造函数私有化并且将拷贝构造和赋值重载删除(或者声明不定义到私有域中),再在类内部提供一个静态成员函数。
解释:

2、演示

class Base2
{
public:
	//通过函数接口在堆上new一个对象出来
	static Base2& NewBase2()
	{
		Base2* b = new Base2;
		return *b;
	}

private:
	//将构造私有化
	Base2(int a = 10) :_a(a)
	{};

	//反拷贝

	//c++98做法 -- 将函数声明不定义加不声明
	//Base2(const Base& b);
	//Base2& operator=(const Base& b);
	 
	//c++11及以后做法 -- 将函数删除
	Base2(const Base2& b) = delete;
	Base2& operator=(const Base2& b) = delete;

	int _a = 0;
};

void test02()
{
	//在栈上不行
	//Base2 b;

	//通过函数接口
	Base2 &b = Base2::NewBase2();

	//不能拷贝
	//Base2 b1(b);
}

三、设计一个只能在栈上创建对象的类

1、方法:将构造函数私有化并且将拷贝构造和赋值重载删除(或者声明不定义到私有域中),需要实现一个移动构造,再在类内部提供一个静态成员函数。
解释:

2、演示

//只允许在栈上
class Base3
{
public:
	static Base3 StackBase3()
	{
		return Base3();
	}

	Base3(Base3&& b):_a(b._a)
	{

	}
private:
	//将构造私有化
	Base3(int a = 10) :_a(a)
	{};

	//反拷贝

	//c++98做法 -- 将函数声明不定义
	//Base3(const Base& b);
	//Base3& operator=(const Base& b);

	//c++11及以后做法 -- 将函数删除
	Base3(const Base3& b) = delete;
	Base3& operator=(const Base3& b) = delete;

	int _a = 0;
};

void test03()
{
	//不能new了
	//Base3* b = new Base3;

	//使用移动构造
	Base3 b = Base3::StackBase3();
	
	//防不了这种情况
//	Base3* b1 = new Base3(move(b));
}

四、设计一个不能被继承的类

1、方法一:将基类构造函数私有,这样派生类就调用不了基类的构造函数,这样就无法继承了。

class Base
{

private:
	Base() {}
};

class Derived:public Base
{
public:
	Derived() :Base()
	{

	}

}

在这里插入图片描述

2、方法二:final关键字,final修饰类,表示该类不能被继承

class Base final
{

private:
	Base() {}
};

class Derived:public Base
{
public:
};

在这里插入图片描述

五、设计一个只能创建一个对象的类(单例模式)

1、单例模式

2、方法一:饿汉模式
(1)概念:就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。
(2)实现细节:

(3)优缺点

(4)演示

//饿汉模式
class Base4
{
public:
	//返回唯一的实例的静态类
	static Base4& RetuntB()
	{
		return b;
	}

	//输出信息
	void Printf()
	{
		cout << s << endl;
	}

private:
	Base4()
	{}
	Base4(const Base4& b) = delete;
	Base4& operator=(const Base4& b) = delete;

private:
	string s = "hello";	//假设这是储存的信息
	static Base4 b;

};

Base4 Base4::b;

void test04()
{
	Base4::RetuntB().Printf();

}

3、方法二:懒汉模式
(1)概念:在使用时再去实例化对象。
(2)实现细节:

(3)优缺点

//懒汉模式
class Base5
{
public:

	//返回唯一的实例的静态类
	static Base5& RetuntP()
	{
		if (p == nullptr)
		{
			p = new Base5;
		}
		
		return *p;
	}

	//输出信息
	void Printf()
	{
		cout << s << endl;
	}

	//释放方法1 --- 实例一个内部类,当内部类释放了,p也会跟着释放
	class DeleteP
	{
	public:
		~DeleteP()
		{
			if (p != nullptr)
				delete p;
		}
	};

	释放方法二 --- 通过手动调用函数释放
	//void DeleteP()
	//{
	//	if (p != nullptr)
	//		delete p;
	//}

private:
	Base5()
	{}
	Base5(const Base5& b) = delete;
	Base5& operator=(const Base5& b) = delete;

private:
	string s = "hello";	//假设这是储存的信息
	static Base5* p;

};

//初始化
Base5* Base5::p = nullptr;

//实例一个内部类,当内部类生命周期结束后会释放 p
Base5::DeleteP del;
举报

相关推荐

0 条评论