1.如何定义一个只能在堆上生成的类
方法一:首先我们要在堆上定义一个对象的时候一定要用new ,比如A *a=new A;
C++会先在堆上malloc一块内存,然后执行构造函数。
相信有些人看到这个题都会这样想:
class A
{
public:
A()
{
return new A;
}
};
看到这里不要笑,因为我一开始有这样想过,为什么不行呢?原因是无限递归调用构造函数,好阔怕。
想到这里既然不能再构造函数里调用new来构造,那就重新定义一个函数Creat()来new,然后在类外调用Creat()完成构造。想到这里,感觉不错。
还没完人家要求只能在堆上生成对象,那么也就是说你要生成一个对象只能调用
Creat(),不能使用构造函数。所以我们只能把构造函数定义为私有。
如果你以为这样就完了,那你还是和我一样年轻。这样做是会报错滴!我直接贴上正确的代码
class C
{
public:
static C* Creat(int c)//如果不加stati会报错,非静态成员与特定对象相对
{
return new C(c);
}
private:
C(int c)
{
_c=c;
}
~C()
{}
int _c;
};
int main()
{
C* c=C::Creat(3);//这里只能由类访问
system("pause");
return 0;
}
至此第一种方法我已经说清楚了。
方法二:这里涉及到一个知识点:编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,其实不光是析构函数,只要是非静态的函数,编译器都会进行检查。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。
所以便有了下面的代码:
class A
{
public :
A(){}
void destory(){ delete this ;}
private :
~A(){}
};
怎么样不难理解吧。
2.如何定义一个只能在栈上生成的类
我们的思路还是和上面差不多,将构造函数设为私有的,然后重新定义一个公有函数调用构造函数。如果你试图在堆上建立一个对象,这样写D* d=new D;那就执行不过去,因为构造函数声明为私有,你无法访问到。
class D
{
public:
static D Creat(int d)
{
return D(d);
}
private:
D(int d)
{
_d=d;
}
int _d;
};
int main()
{
D d=D::Creat(5);
system("pause");
return 0;
}