开头整体说明一下,要求特殊类不能实现的功能,一种方式是将这种方式私有化,另一种方式是用特殊的关键字控制
目录
一、请设计一个类,不能被拷贝
类的拷贝只会在两个场景中出现:一个是构造的时候---拷贝构造,另一个则是赋值的时候。所以只需要将这两种函数禁止访问即可。
第一种:私有化
class A
{
public:
A()
{}
private:
A(const A& x)
{}
A operator=(const A& x)
{}
};
第二种:禁用delete
class A
{
public:
A()
{}
private:
A(const A& x) = delete;
A operator=(const A& x) = delete;
};
二、请设计一个类,只能在堆上创建对象
如果想要用户只能在堆上创建类的话,那就不能让用户直接访问到构造函数和赋值拷贝,因为这种默认的方式都是在栈上创建类对象的
class A
{
public:
static A* create()
{
A* p = new A;
return p;
}
~A()
{
cout << "~A" << endl;
}
private:
A()
{
cout << "A()" << endl;
}
A(const A& x) {}
A operator=(const A& x) {}
};
int main()
{
A::create();
return 0;
}
三、请设计一个类,只能在栈上创建对象
因为只能在栈上创建,所以只需要将new和delete禁用或者私有化即可
class A
{
private:
//void* operator new(size_t x) {}
//void operator delete(void* p) {}
public:
void* operator new(size_t x) = delete;
void operator delete(void* p) = delete;
};
四、请设计一个类,不能被继承
如果一个类不能被继承,可以用final关键字进行修饰这个类;也可以将该类的构造函数进行私有化,在派生类构造中,调不到基类的构造,间接的禁止该类被继承。
第一种:私有化
class A
{
public:
~A()
{}
private:
A()
{}
};
第二种:final关键字
class A final
{
public:
~A()
{}
private:
A()
{}
};
五、请设计一个类,只能创建一个对象(单例模式)
单例模式:就是只能创建一个对象。
单例模式分为两种:饿汉模式,懒汉模式。
饿汉模式:
不管将来用不用,程序启动时就创建一个唯一的实力对象。
饿汉模式:优点:线程安全,性能高;缺点:容易导致资源浪费,不可延时加载
//饿汉模式
class A
{
private:
//声明一个静态的对象
static A a;
//构造函数私有化
A()
{
cout << "A()" << endl;
}
public:
//返回实例
static A* Getinstance1()
{
return &a;
}
~A()
{
cout << "~A()" << endl;
}
//禁用拷贝构造和赋值运算符重载
A(const A& x) = delete;
A operator=(const A& x) = delete;
};
//类内声明,类外定义
A A::a;
懒汉模式:
延迟加载吗,当需要用到时,才创建对象。
懒汉模式:优点:资源利用率高,可延时加载;缺点:线程不安全,性能差(每次调用时,需要同步检查)
不支持线程安全:
//懒汉模式
class A
{
private:
//声明一个静态对象
static A* a;
//构造函数私有化
A()
{}
public:
static A* Geta()
{
if (a == nullptr)
{
a = new A();
return a;
}
}
//禁用拷贝构造和赋值运算符重载
A(const A&) = delete;
A& operator=(const A&) = delete;
};
//类内声明,类外定义
A* A::a = nullptr;
int main()
{
A*p=A::Geta();
return 0;
}
支持线程安全:
//懒汉模式
class A
{
private:
//声明一个静态对象
static A* a;
static std::mutex mtx;
//构造函数私有化
A() {}
public:
static A* Geta()
{
if (a == nullptr)
{
//自动加锁解锁,保证开辟空间的操作是原子的
std::lock_guard<std::mutex> lg(mtx);
a = new A();
}
return a;
}
//禁用拷贝构造和赋值运算符重载
A(const A&) = delete;
A& operator=(const A&) = delete;
};
//类内声明,类外定义
std::mutex A::mtx;
A* A::a = nullptr;
int main()
{
A*p=A::Geta();
return 0;
}