C++动态空间
在C++ 开辟空间,可以使用关键字new,释放空间所用的方法是delete。与C中的malloc类似,在C++中动态开辟的空间依旧是在堆空间上需要手动释放。下面的例子说明了这一过程。
#include<stdio.h>
#include<iostream>
class Rect
{
private:
int pos_x;
int pos_y;
int width;
int height;
char *p;
public:
Rect(int _w, int _h)
{
width = _w;
height = _h;
pos_x = 0;
pos_y = 0;
p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
printf("%s ;地址%p \n\n", p, p);
}
Rect()
{
width = 5;
height = 5;
pos_x = 0;
pos_y = 0;
p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
printf("%s ;地址%p \n\n", p, p);
}
~Rect()
{
free(p);
printf("析构函数被调用,释放地址%p\n\n", p);
}
void set_para(int _w, int _h)
{
width = _w;
height = _h;
}
void show_info()
{
printf("width = %d; height = %d; length = %d\n", width, height, 2 * (width + height));
}
};
int main()
{
{
Rect R1;
//动态创建对象
Rect *R3 = new Rect;
//手动释放
delete R3;
}
Rect R2(2, 3);
getchar();
return 0;
}
从上面的代码可以看出,每创建一个对象,都会在对空间上动态开辟一个空间用来存放指针p;R3的生命周期结束前需要将其手动释放,否则会发生内存的泄露。
对于开辟出来的数组类型的动态空间,在释放时,需要指定释放的空间是数组类型的。
#include<stdio.h>
#include<iostream>
class Rect
{
private:
int pos_x;
int pos_y;
int width;
int height;
char *p;
public:
Rect(int _w, int _h)
{
width = _w;
height = _h;
pos_x = 0;
pos_y = 0;
p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
printf("%s ;地址%p \n\n", p, p);
}
Rect()
{
width = 5;
height = 5;
pos_x = 0;
pos_y = 0;
p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
printf("%s ;地址%p \n\n", p, p);
}
~Rect()
{
free(p);
printf("析构函数被调用,释放地址%p\n\n", p);
}
void set_para(int _w, int _h)
{
width = _w;
height = _h;
}
void show_info()
{
printf("width = %d; height = %d; length = %d\n", width, height, 2 * (width + height));
}
};
int main()
{
{
Rect R1;
Rect *R3 = new Rect[10];
delete[] R3;
}
Rect R2(2, 3);
getchar();
return 0;
}
拷贝构造函数
拷贝构造和默认构造函数类似,在创建新对象时会自动调用。拷贝构造函数中含有拷贝过程,将一个对象中的成员变量赋值给新对象中的成员,但是有时候需要深度拷贝时,需要注意对象的生存周期。拷贝函数的名字和类名相同,拷贝过程中,需要传递一个变量的引用。
调用拷贝构造函数时,有如下三种情况:
- 由显示或隐式的方法,使用一个对象来创建一个新对象时
- 函数传递参数时,传递的参数是一个对象时,接收参数时调用拷贝构造函数
- 函数返回值是一个对象,并且用这个返回值创建了一个新的对象使,会调用构造函数
#include<stdio.h>
#include<iostream>
class Rect
{
private:
int pos_x;
int pos_y;
int width;
int height;
char *p;
public:
Rect(int _w, int _h)
{
width = _w;
height = _h;
pos_x = 0;
pos_y = 0;
p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
printf("%s ;地址%p \n\n", p, p);
}
Rect()
{
width = 5;
height = 5;
pos_x = 0;
pos_y = 0;
p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
printf("%s ;地址%p \n\n", p, p);
}
Rect( Rect & _r)
{
pos_x = _r.pos_x;
pos_y = _r.pos_y;
width = _r.width;
height = _r.height;
p = (char *)malloc(sizeof("RECT 构建由拷贝构造函数完成"));
memcpy(p, "RECT 构建由拷贝构造函数完成", sizeof("RECT 构建由拷贝构造函数完成"));
printf("%s ;地址%p \n\n", p, p);
}
~Rect()
{
free(p);
printf("析构函数被调用,释放地址%p\n\n", p);
}
void set_para(int _w, int _h)
{
width = _w;
height = _h;
}
void show_info()
{
printf("width = %d; height = %d; length = %d\n", width, height, 2 * (width + height));
}
};
void test(Rect r)
{
r.show_info();
}
Rect test_a(int w, int h)
{
Rect R1(1, 5);
return R1;
}
int main()
{
{
//创建对象
Rect R1;
//拷贝方式创建对象
Rect R3 = R1;
//传递参数是对象时,调用拷贝构造函数
test(R3);
//接收返回值是对象时,调用拷贝构造函数
Rect R4 = test_a(1, 5);
}
Rect R2(2, 3);
getchar();
return 0;
}