设计一个只能在堆上创建对象的类
实现类的条件
1.构造函数私有化
2.提供公共接口:在堆上创建对象
3.在类外面无法创建对象,函数用类名调用,公共接口必须为static接口
4.防止拷贝:
<1>:拷贝构造私有化,只声明不实现
<2>:拷贝构造声明成delete函数(C++11的特性)
#include<iostream>
//设计一个只能在堆上申请对象的类
using namespace std;
class HeapOnly{
public:
static HeapOnly* creatHeapOnly(){
return new HeapOnly;
}
private:
HeapOnly(){
cout << "HeapOnly" << endl;
}
HeapOnly(const HeapOnly& h){
cout << "HeapOnly(const HeapOnly&)" << endl;
}
};
int main(){
HeapOnly* h=HeapOnly::creatHeapOnly();
//此时不能用HeapOnly h的方式申请对象,因为
//该类的构造函数已经被私有化了。
HeapOnly h1(*h);
return 0;
}
如果只是将拷贝构造函数私有化的话阻止在栈上创建对象是否有用?
这种方式只是阻止了在主函数中使用拷贝构造函数创建对像。并不能完全将拷贝构造函数的调用路径完全 “堵住”
再看下面的程序
#include<iostream>
//设计一个只能在堆上申请对象的类
using namespace std;
class HeapOnly{
friend void fun();
public:
static HeapOnly* creatHeapOnly(){
return new HeapOnly;
}
private:
HeapOnly(){
cout << "HeapOnly" << endl;
}
//如果不将拷贝构造也"堵住"的话,还是可以将对象创建在栈上
//也可以将拷贝构造函数只声明不实现
HeapOnly(const HeapOnly& h){
cout << "HeapOnly(const HeapOnly&)" << endl;
}
};
void fun(){
HeapOnly *h=HeapOnly::creatHeapOnly();
HeapOnly h1(*h);
//如果不将拷贝构造函数delete,这种方式就可以调用拷贝构造
}
int main(){
fun();
return 0;
}
可以看到只是简单的将拷贝构造函数私有化是阻止不了拷贝构造函数的调用的。我们可以通过友元函数的方法来实现对象的创建,
如下图
通过上图可以看到,就算拷贝构造函数私有化了我们也可以通过友元函数的方式调用,而且不影响函数的使用。那到底怎样才能真真的将拷贝构造函数 “堵死” 呢?
看下例
#include<iostream>
//设计一个只能在堆上申请对象的类
using namespace std;
class HeapOnly{
friend void fun();
public:
static HeapOnly* creatHeapOnly(){
return new HeapOnly;
}
private:
HeapOnly(){
cout << "HeapOnly" << endl;
}
HeapOnly(const HeapOnly& h) = delete;
//如果不将拷贝构造也"堵住"的话,还是可以将对象创建在栈上
};
void fun(){
HeapOnly *h=HeapOnly::creatHeapOnly();
HeapOnly h1(*h);
//如果不将拷贝构造函数delete,这种方式就可以调用拷贝构造
}
int main(){
fun();
return 0;
}
我们可以直接将拷贝构造函数给 delete 掉。这样就彻底的将拷贝构造函数 堵死 了,我们只能在对象创建对象了。
也可以将拷贝构造的 delete 函数公有化,因为不管私有还是公有都没办法访问到已经删除的函数。也可以通过只声明不实现的方式实现该功能
【注意】
在实现该类的过程中,千万不能以为只是将构造函数和拷贝构造函数私有化就可以阻止在栈上创建对象.