zoukankan      html  css  js  c++  java
  • 只能用new生成的对象 Anthony

     

    new生成的对象,在面向对象中是很有用的.它保存在堆上,可以自由控制生命周期。

    但如何保证一个对象只能在堆上生成呢?

    答案其实也很简单,只需把析构函数定义为私有成员。例如OnlyCanBeNew类定义。

       1|     class OnlyCanBeNew

       2|     {

       3|         ~OnlyCanBeNew(){}

       4|     public:

       5|         OnlyCanBeNew(){}

       6|     };

    原因呢,C++是一个静态绑定的语言。在编译过程中,所有的非虚函数调用都必须分析完成。即使是虚函数,也需检查可访问性。因些,当在栈上生成对象时,对象会自动析构,也就说析构函数必须可以访问。而堆上生成对象,由于析构时机由程序员控制,所以不一定需要析构函数。

    保证了不能在栈上生成对象后,需要证明能在堆上生成它。这里OnlyCanNew与一般对象唯一的区别在于它的析构函数为私有。delete操作会调用析构函数。所以不能编译。那么如何释放它呢?

    答案也很简单,提供一个成员函数,完成delete操作。在成员函数中,析构函数是可以访问的。当然detele操作也是可以编译通过。

       7|         void OnlyCanBeNew::Destroy()

       8|         {  

       9|             delete this;

    10|         }

    回到起点,如果需要再在栈上使用这个对象,怎么办呢。那就要用到包装了。类似Wrap类这样的类,如果它与OnlyCanBeNew接口的一样。那么在栈上使用它,就与使用OnlyCanBeNew一样了。

    11|     #include <stdio.h>

    12|      

    13|     class Wrap;

    14|     class OnlyCanBeNew

    15|     {

    16|         friend class Wrap;

    17|         ~OnlyCanBeNew(){}

    18|     public:

    19|         OnlyCanBeNew(){}

    20|         void Destroy()

    21|         {  

    22|             delete this;

    23|         }

    24|     };

    25|      

    26|     class Wrap

    27|     {

    28|         OnlyCanBeNew *p;

    29|     public:

    30|         Wrap(): p(new OnlyCanBeNew)

    31|         {

    32|         }

    33|      

    34|         ~Wrap()

    35|         {

    36|             p->Destroy();

    37|         }

    38|      

    39|     };

    测试代码如下:

    40|     int main(int argc, char *argv[])

    41|     {

    42|         OnlyCanBeNew one; //编译错误

    43|      

    44|         Wrap some; //OK

    45|         OnlyCanBeNew * p = new OnlyCanBeNew; //OK

    46|      

    47|         p->Destroy(); //释放

    48|         printf("Hello, world/n");

    49|        

    50|         return 0;

    51|     }

  • 相关阅读:
    分页查询SQL语句
    屏蔽Ctrl+C
    RichtextBox 控件小节
    必须掌握的八个CMD命令
    [唠叨两句]一个关于OpenFileDialog 影响 相对路径的问题
    反序列化出现异常:SerializationException 在分析完成之前就遇到流结尾
    Static块(静态代码块)
    Java ServletContext 详解
    tomcat中conf\Catalina\localhost目录下的J2EE项目METAINF配置文件
    关于【apache tomcat 5.5.15/conf /Catalina/localhost配置虚拟目录】时的一些问题。(配置web项目的方式不止一种,虚拟目录就是一个)
  • 原文地址:https://www.cnblogs.com/ahuangliang/p/5309279.html
Copyright © 2011-2022 走看看