我们知道,string类内部的构造函数是采用new来分配地址的。当创建对象时,会调用string的构造函数,从而实质上也使用了new。那么问题来了,如果我用new再创建一个string类型的指针呢?下面先来看我自己定义的String类。(注意:不是标准string类)
1 #ifndef STRING6_H_
2 #define STRING6_H_
3 #include <cstring>
4
5 class String
6 {
7 private:
8 char *
str;
9 int len;
10
11 public:
12 String();
13 String(
const char *
s);
14 ~
String();
15 };
16
17 String::String()
18 {
19 len =
4;
20 str =
new char[len +
1];
21 str[
0] =
'\0';
22 std::cout <<
"String create in String():\n";
23 }
24
25 String::String(
const char *
s)
26 {
27 len =
std::strlen(s);
28 str =
new char[len +
1];
29 std::strcpy(str, s);
30 std::cout <<
"string create!\n";
31 std::cout <<
"(void*)str in class:" << (
void*) str <<
std::endl;
32 }
这是一个简单的类,主要测试构造函数用new分配内存的情况。再来看看实质使用:
1 #include <iostream>
2 #include <
string>
3 #include
"string_6.h"
4
5 int main(
void)
6 {
7 using namespace std;
8
9 String * pStr =
new String(
"hehehe");
10 cout <<
"(void*)pStr: " << (
void*)pStr <<
endl;
11 delete pStr;
12
13 String * pStr1 =
new String(
"I am a man!");
14 cout <<
"(void*)pStr1: " << (
void*)pStr1 <<
endl;
15 delete pStr1;
16
17 String * pStr2 =
new String(
"I am a chinese!");
18 cout <<
"(void*)pStr2: " << (
void*)pStr2 <<
endl;
19 delete pStr2;
20
21 return 0;
22 }
23 /*****************************
24 * string create!
25 * (void*)str in class:0xa84c40
26 * (void*)pStr: 0xa84c20
27 * String delete!
28 * string create!
29 * (void*)str in class:0xa84c40
30 * (void*)pStr1: 0xa84c20
31 * String delete!
32 * string create!
33 * (void*)str in class:0xa84c40
34 * (void*)pStr2: 0xa84c20
35 * String delete!
36 * ***************************/
本身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使用国的内存。所以我们看到后面的地址输出和前面的是一样的。
转载于:https://www.cnblogs.com/busui/p/5817315.html