1.请设计一个类,不能被拷贝
拷贝只会放生在两个场景中:拷贝构造函数和赋值运算符重载
c++98
将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可
class Copyban{
Copyban(const Copyban&);
Copyban operator=(const Copyban&);
}
①.设置成私有:如果只声明没有设置成private,用户自己在类外定义了,就可以不能禁止拷贝了
②.只声明不定义:不定义是因为该函数根本不会调用吗,定义了没意义,而且如果定义了就不会防止成员函数内部拷贝了
C++1
C++11扩展delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟上=delete,表示让编译器删除掉该默认成员函数。
class CopyBan
{
CopyBan(const CopyBan&)=delete;
CopyBan& operator=(const CopyBan&)=delete;
};
2.设计一个类,只能在堆上创建对象
方案一:析构函数私有化
class Heaponly{
static void Destroy(Heaponly*ptr){
delete ptr;
}
void Destroy{
delete this;
}
private:
~Heaponly(){
}
}
int main(){
Heaponly*ptr=new Heaponly;
Heaponly::destroy(ptr);
// ptr->destroy();
}
我们可以将析构函数私有化,因为在栈上和静态区的对象需要自动调用析构函数,而析构函数无法显示调用了,就会导致我们无法在栈上和静态区创建对象。
因为堆上的对象是需要我们手动的创建和删除的,所以在堆上创建对象只先调用构造函数; 如果我们需要对堆上创建的对象进行销毁,我们可以提供一个公有函数接口,用这个函数接口调用私有函数。
方案二:构造函数私有化
class Heaponly{
public:
static Heaponly*createObj(){
return new HeapOnly;
}
Heaponly(const Heaponly&hp)=delete;
Heaponly&operator=(const Heaponly&hp)=delete;
private:
Heaponly(){
}
}
int main(){
Heaponly*ptr=Heaponly:createObj();
}
我们将构造函数私有,禁止任何方式创建示例。但是提供一个可以在堆上创建对象的公有函数,这样我们就可以通过公有函数来调用私有的构造函数。这里的要创建对象的公有函数应该是static修饰的,因为如果要调用公有函数,需要有一个对象示例,而我们要用公有函数创建一个示例,而我们现在没有对象示例,需要调用公有函数(类似鸡生蛋,蛋生鸡)…如果函数在静态区,就可以直接调用了。同时,为了防止我们创建的对象示例被拷贝构造或者赋值,所以我们还需要将拷贝构造函数和赋值运算符重载函数封死。
3.设计一个类,只能在栈上创建对象
构造函数私有化
class StackOnly
{
public:
static StackOnly CreateObj()
{
StackOnly st;
return st;
}
private:
StackOnly()
{
}
//对一个类实现专属的operator new
//如果对一个类实现一个专属的operator new,那么会调这个
void* operator new(size_t size) = delete;
};
int main()
{
StackOnly hp3 = StackOnly::CreateObj();
StackOnly copy(hp3);
}
4.设计一个类、不能被继承
C++98
我们将构造函数私有化,派生类中调不到基类的构造函数,则无法继承。
class NonInherit
{
public:
static NonInherit GetInstance()
{
return NonInherit();
}
private:
NonInherit()
{
}
}
C++11 final
class A final
{
};