构造函数初始化列表
当类的成员变量中存在类时候,同时成员类没有无参或默认构造函数,在创建该类的对象时候会出错。这是需要使用初始化列表。将需要的成员变量进行初始化。
- 初始化列表的初始化顺序是按成员变量的定义顺序进行初始化,最后执行到构造函数内部。
- 析构函数的执行顺序与构造时候相反。
//Rect.h
#include "Point.h"
class Rect {
private:
int index;
Point p2;
Point p1;
public:
Rect(int index, int x1, int x2);
~Rect();
void print();
};
//Rect.cpp
Rect::Rect(int index, int x1, int x2):p1(x1,0,"name is p1"),p2(x2,0,"name is p2") {
this->index=index;
}
拷贝构造函数调用时机
- 一个对象赋值给另一个对象
Point p2 = p1;
- 构造函数中作为参数传入
Point p3(p1);
- 函数调用时,存在类作为参数,实参到形参。
void printPoint(Point point) { cout << point.getX() << " " << point.getY() << endl; }
- 函数返回值为对象时候(编译器会做优化,可能不会调用)。
Point getPoint() { Point p(10, 20); return p; }
示例
Point.h
class Point {
private:
int x;
int y;
public:
Point(int x, int y);
Point(int x);
Point();
int getX() const;
void setX(int x);
int getY() const;
void setY(int y);
virtual ~Point();
Point(const Point&);
};
Point.cpp
#include "iostream"
#include "Point.h"
using namespace std;
int Point::getX() const {
return x;
}
void Point::setX(int x) {
Point::x = x;
}
int Point::getY() const {
return y;
}
void Point::setY(int y) {
Point::y = y;
}
Point::Point(int x, int y) : x(x), y(y) {
this->x = x;
this->y = y;
cout << "Point(x=" << x << ",y=" << y << ")" << endl;
}
Point::Point(int x) : x(x) {
this->x = x;
cout << "Point(x=" << x << ")" << endl;
}
Point::Point() {
cout << "Point()" << endl;
}
Point::~Point() {
cout << "~Point()" << endl;
}
Point::Point(const Point &point) {
this->x = point.x + 100;
this->y = point.y + 100;
cout << "Point(const Point &point)" << endl;
}
结果:
Point(x=1,y=2)
----
Point(const Point &point)
----
Point(const Point &point)
----
Point(const Point &point)
101 102
~Point()
----
Point(x=1,y=2)
~Point()
~Point()
~Point()
~Point()
浅拷贝、深拷贝
- 默认的copy构造函数和赋值操作是浅拷贝。值拷贝成员变量的值。当成员变量中存在指针时候,释放内存空间时,会出现野指针问题。
这时候需要重写copy构造函数。如:
Point::Point(const Point &point) {
this->x = point.x + 100;
this->y = point.y + 100;
if (point.getName() != NULL) {
int len = strlen(point.getName());
this->name = (char *) malloc((sizeof(char)) * (len + 1));
strcpy(this->name, point.getName());
}
cout << "Point(const Point &point)" << endl;
}