Allocating Class instances using new
new operator 也可以用于对class instance分配动态内存。
如下例:
#include <iostream>
using namespace std;
class Point {
public:
Point() {
x = 0; y = 0;
cout << "default constructor" << endl;
}
private:
int x;
int y;
};
int main() {
Point *p = new Point;
delete p;
}
执行结果如下:
再比如, 我们定义一个有参数的constructor:
#include <iostream>
using namespace std;
class Point {
public:
Point() {
x = 0; y = 0;
cout << "default constructor" << endl;
}
Point(int nx, int ny) {
int x= nx;
int y = ny;
cout << "2-arg constructor" << endl;
}
private:
int x;
int y;
};
int main() {
Point *p = new Point(2, 4);
delete p;
return 0;
}
执行结果
Destructor(解构子)
当我们的class instance 被deallocated 的时候, 就会调用destructor。
如下:
class Point {
public:
Point() {
x = 0; y = 0;
cout << "default constructor" << endl;
}
Point(int nx, int ny) {
int x= nx;
int y = ny;
cout << "2-arg constructor" << endl;
}
~Point() {
cout << "destructor invoked" << endl;
}
private:
int x;
int y;
};
全体程序如下:
#include <iostream>
using namespace std;
class Point {
public:
Point() {
x = 0; y = 0;
cout << "default constructor" << endl;
}
Point(int nx, int ny) {
int x= nx;
int y = ny;
cout << "2-arg constructor" << endl;
}
~Point() {
cout << "destructor invoked" << endl;
}
private:
int x;
int y;
};
int main() {
Point *p = new Point(2, 4);
delete p;
return 0;
}
运行之后, 得到:
注意, 如果采用new 为对象动态分配内存时, 必须采用delete, 才会调用destructor。 如上。
如果对象是stack-allocated, 当对象goes out of scope, 才会调用解构子。
#include <iostream>
using namespace std;
class Point {
public:
Point() {
x = 0; y = 0;
cout << "default constructor" << endl;
}
Point(int nx, int ny) {
int x= nx;
int y = ny;
cout << "2-arg constructor" << endl;
}
~Point() {
cout << "destructor invoked" << endl;
}
private:
int x;
int y;
};
int main() {
if (true) {
Point p;
}
cout << "p out of scope" << endl;
return 0;
}
运行结构如下:
下面, 我们编写一个类去representing an array of integers.。 不难看出, 成员变量不仅需要一个指向数组第一个元素的指针, 也需要有数组元素个数的信息。
注意当建构子中使用了动态内存分配(new), 那么在解构子中必须要释放这些动态内存(delete)。 如果没有分配动态内存, 那么
解构子的函数体内可以什么也不写。
下面举一个例子:
#include <iostream>
using namespace std;
class IntegerArray {
public:
int *data;
int size;
IntegerArray(int size = 0) {
data = new int[size];
this->size = size;
}
~IntegerArray() {
delete[] data;
}
};
int main() {
IntegerArray a(2);
a.data[0] = 4; a.data[1] = 2;
if (true) {
IntegerArray b = a;// 错的原因是由于没有定义赋值建构子,所以只是将b 指向了对象a的地址,也就是说a ,b 为同一个对象, 当b 解构的时候,a也没有了
}
cout << a.data[0] << endl; // not 4, why????
return 0;
}
上述执行的结果为:
出错, 下面给出解释:
也就是说, 当b goes out of scope, 就会呼叫的destructor, 用于deallocates array, 现在a.data 变成了一个dangling pointer。
除此之外, 还有一个bug, 就是当a goes out of scope, its constructor tries to delete (already deleted ) array。
如何消除这两个bugs 呢? 解决办法就是写出一个copy constructor(赋值建构子):
#include <iostream>
using namespace std;
class IntegerArray {
public:
int *data;
int size;
IntegerArray(int size = 0) {
data = new int[size];
this->size = size;
}
//copy constructors
IntegerArray(IntegerArray &o) { //别名
data = new int[o.size];
size = o.size;
for (int i = 0; i < size; ++i) {
data[i] = o.data[i];
}
}
~IntegerArray() {
delete[] data;
}
};
int main() {
IntegerArray a(2);
a.data[0] = 4; a.data[1] = 2;
if (true) {
IntegerArray b = a;
}
cout << a.data[0] << endl;
return 0;
}
运行结果如下:
分析见如下两幅图: