文章目录
一、设计一个不允许拷贝的类
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;