C++作为一门强大的编程语言,在面向对象编程(OOP)领域占据着举足轻重的地位。在C++的OOP中,类(Class)是基础,而构造函数和拷贝控制则是实现类实例创建、初始化和复制的核心机制。
1.无参构造函数
无参构造函数是类的一个特殊成员函数,它在创建类的新对象时被自动调用,用于初始化对象的数据成员。当定义一个类时,如果没有显式定义任何构造函数,编译器会自动生成一个默认的无参构造函数。这个默认构造函数通常执行一些基本的初始化操作。
class MyClass {
public:
MyClass() {
// 无参构造函数体
}
};
在上面的例子中,MyClass是一个类,它有一个无参构造函数。当创建MyClass的实例时,如MyClass obj;,这个无参构造函数将被调用。
2、带参构造函数
带参构造函数允许我们在创建对象时传递参数,根据传递的参数初始化对象的数据成员。带参构造函数可以有多个,只要每个构造函数的参数列表不同即可。
class MyClass {
private:
int value;
public:
MyClass(int val) : value(val) {
// 带参构造函数体
}
};
在这个例子中,MyClass有一个带参数val的构造函数。当创建对象时,如MyClass obj(10);,传递的参数10将被用来初始化value数据成员。
3.拷贝构造函数
拷贝构造函数用于创建一个对象并将其初始化为另一个同类对象的副本。拷贝构造函数通常在以下情况下被调用:
- 当用一个已存在的对象初始化新对象时。
- 当函数的参数是类对象时,会使用拷贝构造函数传递实参的副本。
- 当函数的返回值是类对象时,会使用拷贝构造函数复制返回值。
如果程序员没有显式定义拷贝构造函数,编译器会自动生成一个。编译器生成的拷贝构造函数执行的是浅拷贝。
class MyClass {
private:
int* data;
public:
MyClass(const MyClass& other) {
// 拷贝构造函数体
data = new int(*other.data); // 深拷贝
}
};
在上面的例子中,MyClass有一个拷贝构造函数,它通过深拷贝来复制other对象的数据成员。
4.深拷贝与浅拷贝
浅拷贝和深拷贝是拷贝构造函数执行的两种不同的复制方式:
- 浅拷贝:简单地复制对象的成员变量,包括指针成员。如果指针成员指向了动态分配的内存,那么浅拷贝会导致两个对象共享同一块内存,可能会引发诸如内存泄漏、数据不一致等问题。
- 深拷贝:复制对象的所有成员变量,并且复制指针成员指向的动态分配的内存。这样每个对象都有自己的内存副本,避免了上述问题。
在实际应用中,如果类中有指针成员,通常需要自定义拷贝构造函数来实现深拷贝。
下面分别给出一个深拷贝和浅拷贝的例子,以便更好地理解这两种拷贝方式的区别。
为了展示深拷贝和浅拷贝在内存分配上的不同,打印出拷贝前后对象的内存地址。这样我们可以清楚地看到,浅拷贝会导致两个对象共享相同的内存地址,而深拷贝则会使每个对象拥有自己的内存地址。
浅拷贝例子:
#include
class ShallowCopy {
public:
int* data;
// 构造函数
ShallowCopy(int val) {
data = new int(val);
std::cout