我们可能有时候会被问到C++的一写特殊类, 只能在堆上创建对象, 只能在栈上创建对象, 或者不能被继承的类.
那么怎么设计呢? 让我们一起来学习~
只能在堆上创建对象的类
只能在堆上申请空间, 也就是只能动态申请
不能在栈上创建对象, 所以我们首先就不能让构造函数随便被调用
首先要将构造函数私有化
构造函数私有化之后, 也无法在堆上创建对象
所以我们要提供一个接口供外部调用, 通过这个接口创建对象
因为构造函数已经私有化, 所以现在已经无法实例化对象, 也就无法调用接口, 但是静态成员可以直接通过类名访问
所以这里提供一个静态的公有接口, 通过类名直接在堆上创建对象
这里一定是返回地址
虽然构造函数私有化了, 但是还有拷贝构造
我可以先在堆上创建对象, 然后调用拷贝构造依然可以创建栈上的对象
所以这里还需要进行防拷贝的操作, 有两种方法
1. 只声明不实现
2. 直接定义成delete函数
建议使用第二种, 比较彻底 0.0
具体代码如下:
//只能在堆上创建的对象
class HeapOnly {
public:
//静态公有的方法,创建对象
static HeapOnly* getobj() {
//堆上创建对象
return new HeapOnly;
}
private:
//构造函数私有化
HeapOnly() { }
//防拷贝:
//1. 声明不实现
HeapOnly(const HeapOnly& ho);
//2. 直接定义成delete函数
HeapOnly(const HeapOnly& ho) = delete;
};
void test() {
//栈上的对象:自动调用公有的无参默认构造
//HeapOnly ho;
//堆上的对象
HeapOnly* ptr = HeapOnly::getobj();
}
只能在栈上创建对象的类
第一种方法
这种方法和上面的方法一样
构造函数私有化 + 静态的公有接口
这是就是返回值即可, 也不用防拷贝, 毕竟在栈上创建
具体代码如下:
//只能在栈上创建的对象
class StackOnly {
public:
//静态公有方法, 在栈上创建对象
static StackOnly getobj() {
StackOnly so;
return so;
}
//拷贝构造不用管, 本来就在栈上
private:
//构造函数私有化
StackOnly() {}
};
第二种方法
既然不让在堆上申请空间, 还是自定义类型 (通过调用operator new来申请空间)
那我直接把operator new和operator delete禁掉不就行了
//第二种方法
class StackOnly2 {
public:
//重定义operator new/delete, 定义成删除函数
void* operator new(size_t n) = delete;
void operator delete(void* ptr) = delete;
};
不能被继承的类
这个就非常简单了
第一种方法是直接把父类声明为final类,禁止继承
第二种是把父类构造私有化, 子类无法调用父类构造也就无法实例化对象, 继承了也没用
//设计一个不能被继承的类
//1. 声明为final类
class Base1 final {
};
//2. 父类构造私有化 (继承后子类无法实例化对象)
class Base {
private:
Base()
{}
};