我们知道,string类内部的构造函数是采用new来分配地址的。当创建对象时,会调用string的构造函数,从而实质上也使用了new。那么问题来了,如果我用new再创建一个string类型的指针呢?下面先来看我自己定义的String类。(注意:不是标准string类)

 #ifndef STRING6_H_
#define STRING6_H_
#include <cstring> class String
{
private:
char * str;
int len; public:
String();
String(const char * s);
~String();
}; String::String()
{
len = ;
str = new char[len + ];
str[] = '\0';
std::cout << "String create in String():\n";
} String::String(const char * s)
{
len = std::strlen(s);
str = new char[len + ];
std::strcpy(str, s);
std::cout << "string create!\n";
std::cout << "(void*)str in class:" << (void*) str << std::endl;
}

这是一个简单的类,主要测试构造函数用new分配内存的情况。再来看看实质使用:

 #include <iostream>
#include <string>
#include "string_6.h" int main(void)
{
using namespace std; String * pStr = new String("hehehe");
cout << "(void*)pStr: " << (void*)pStr << endl;
delete pStr; String * pStr1 = new String("I am a man!");
cout << "(void*)pStr1: " << (void*)pStr1 << endl;
delete pStr1; String * pStr2 = new String("I am a chinese!");
cout << "(void*)pStr2: " << (void*)pStr2 << endl;
delete pStr2; return ;
}
/*****************************
* string create!
* (void*)str in class:0xa84c40
* (void*)pStr: 0xa84c20
* String delete!
* string create!
* (void*)str in class:0xa84c40
* (void*)pStr1: 0xa84c20
* String delete!
* string create!
* (void*)str in class:0xa84c40
* (void*)pStr2: 0xa84c20
* String delete!
* ***************************/

本身String类里的构造函数已经用类new,我再main函数里再用一次new来创建一个String类型的指针。现在我们单单来看这一句:String * pStr = new String("hehehe"); ,这一句的步骤是:先用new分配一个String类型的无名地址,然后再调用String类的构造函数,然后这个构造函数再用new分配另一个地址,并且用“heheh”初始化。再然后String类再将“heheh”存储到开始new创建的无名地址。最后将pStr指向这个无名地址。所以我们看到(void*)pStr: 0xa84c20 的地址要比 (void*)str in class:0xa84c40 排得靠前。
之后我们来看看第一个delete语句,它是删除再main函数中new分配的内存的,在调用这个delete的前一瞬间触发了String类的析构函数,这个析构函数里面也有一个delete(看上面代码就清楚了),执行完析构函数中的delete后再执行main中的delete。至此,关于pStr的点点第第也就结束了。它用过的地址,也就被归还给系统了。当我们故技重施,会发现,后面的类型一样的语句会重新使用pStr使用国的内存。所以我们看到后面的地址输出和前面的是一样的。

对类对象使用new时地址分配的情况的更多相关文章

  1. 当我们用自定义的类对象作为key时,我们必须在程序中覆盖HashCode()和equals()。

    Key值既然可以作为对象,那么也可以用一个自定义的类.比如: m.put(new sutdent(“Liucy”,30),”boss”) 如果没有语句来判定Student类对象是否相同,则会全部打印出 ...

  2. delete 类对象指针的注意事项]

    http://blog.csdn.net/infoworld/article/details/45560219 场景:1. C++类有构造和析构函数,析构函数是在类对象被delete时(或局部变量自动 ...

  3. c++类对象的内存分布

    要想知道c++类对象的内存布局, 可以有多种方式,比如: 1)输出成员变量的偏移, 通过offsetof宏来得到 2)通过调试器查看, 比如常用的VS 1.没有数据成员的对象 class A{ }; ...

  4. Python类对象

    python类对象 python类对象支持两种操作:属性引用和实例化. 属性引用 使用 Python 中所有属性引用所使用的标准语法: obj.name. 有效的属性名称是类对象被创建时存在于类命名空 ...

  5. 关于c++11中static类对象构造函数线程安全的验证

    在c++11中,static静态类对象在执行构造函数进行初始化的过程是线程安全的,有了这个特征,我们可以自己动手轻松的实现单例类,关于如何实现线程安全的单例类,请查看c++:自己动手实现线程安全的c+ ...

  6. Python - 面向对象编程 - 什么是 Python 类、类对象、实例对象

    什么是对象和类 https://www.cnblogs.com/poloyy/p/15178423.html Python 类 类定义语法 最简单的类定义看起来像这样 class ClassName: ...

  7. Qt窗体关闭时,如何自动销毁窗体类对象

    Qt窗体关闭时,如何自动销毁窗体类对象     要对你的窗口设置WA_DeleteOnClose属性,默认的情况下关闭窗口仅仅意味着隐藏它 ImgWindow1->setAttribute(Qt ...

  8. 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针

      您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...

  9. c++,类的对象作为形参时一定会调用复制构造函数吗?

    c++,类的对象作为形参时一定会调用复制构造函数吗? 答:如果参数是引用传递,则不会调用任何构造函数:如果是按值传递,则调用复制构造函数,按参数的值构造一个临时对象,这个临时对象仅仅在函数执行是存在, ...

随机推荐

  1. POPTEST老李推荐:互联网时代100本必读书,来自100位业界大咖推荐 2

    ➤NO.30<移动的力量>[推荐人]刘九如:电子工业出版社副社长兼总编辑邬贺铨:中国工程院院士.原副院长汪力成:华立集团董事局主席➤NO.31<智慧社会>[推荐人]段永朝:财讯 ...

  2. 老李分享:Android性能优化之内存泄漏3

    线程造成的内存泄漏 对于线程造成的内存泄漏,也是平时比较常见的,如下这两个示例可能每个人都这样写过: //——————test1 new AsyncTask<Void, Void, Void&g ...

  3. Android中的java层的线程暂停和恢复实现

    /**  * 基础线程对象.  *  * @author jevan  * @version (1.0 at 2013-6-17)  * @version (1.1 at 2013-7-2) 增加on ...

  4. Redis基础学习(四)—Redis的持久化

    一.概述      Redis的强大性能很大程度上都是因为数据时存在内存中的,然而当Redis重启时,所有存储在内存中的数据将会丢失,所以我们要将内存中的数据持久化. Redis支持两种数据持久化的方 ...

  5. spring mvc mybatis集成踩的坑

    开园这么多年了也没写几篇文章,现在想想光看别人的也不行啊,咱也自己写写,就写这天我我在做spring mvc与mybatis的集成时遇到的问题 1 spring与mybatis的集成 这个相信大家都弄 ...

  6. Redis数据类型之列表List

    Redis列表简介 Redis列表是简单的字符串列表,一个列表最多可以包含 232 - 1 个元素.列表按照插入顺序排序,可以从列表的头部或者尾部添加元素 上图演示了使用LPUSH向列表中插入元素,并 ...

  7. iOS获取视频中的指定帧的两种方法

    方法一 :AVFoundation #import <AVFoundation/AVFoundation.h> - (UIImage *)thumbnailImageForVideo:(N ...

  8. 区分词法作用域(js)与动态作用域(精!)

    在js学习中,词法作用域是必须要掌握的! 在这里,我将总结一下<你不知道的JS>一书中词法作用域的重点并分享给大家! 首先带来一段代码示例: function foo(){ console ...

  9. Java匿名内部类使用与示例

    首先说为什么有匿名类 两个原因(产生的使命) 1.简化代码编写 某种情况下,类只需要扩展一个方法,没必要为了一个方法单独去写一个子类,然后然后调用子类,此时需要匿名类 2.在不同的包内的类内调用类的p ...

  10. C语言学习第七章

    今天开始学习指针,指针在C语言中具有很重要的地位,按照老师所说,学C学不好指针跟没学一样,可见指针在C语言中的重要地位.废话不多说,首先我们先要知道什么是指针. 指针:指针是一个变量,它存储另一个对象 ...