何时在C++中创建默认构造函数和复制构造函数?
在C++中,每个类都必须有构造函数。如果程序员没有定义构造函数,在编译时编译器会自动生成一个默认的构造函数。默认构造函数对于大多数类来说是足够的,但在某些情况下,程序员需要创建自己的构造函数。
默认构造函数
默认构造函数是没有参数的构造函数。如果程序员没有定义构造函数,编译器会自动生成一个默认构造函数。如果类中的数据成员都是基本类型或没有初始化,可以使用默认构造函数。例如:
class MyClass {
int x;
char y;
public:
void print() {
cout << "x: " << x << ", y: " << y << endl;
}
};
int main() {
MyClass obj; // 默认构造函数被调用
obj.print(); // 输出: x: 0, y:
return 0;
}
上述代码中,因为没有定义构造函数,编译器自动生成了一个默认构造函数。MyClass的对象obj使用默认构造函数被创建。
复制构造函数
复制构造函数是一个接受一个同类型参数的构造函数。它在创建一个新对象时,使用另一个同类型的对象作为参数进行构造。例如:
class Student {
string name;
int age;
public:
Student(string n, int a) {
name = n;
age = a;
}
void print() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Student s1("John", 20);
Student s2 = s1; // 复制构造函数被调用
s1.print(); // 输出: Name: John, Age: 20
s2.print(); // 输出: Name: John, Age: 20
return 0;
}
上述代码中,我们定义了一个Student类,它有一个带参数的构造函数。然后我们创建了两个对象s1和s2。s2使用s1的值来初始化。这里复制构造函数被调用了。
有三种情况下,程序员需要自己创建复制构造函数:
- 类中有指针变量。
- 类中有动态分配的内存。
- 类中有文件或网络连接。
下面是几个具体的例子:
例子1:类中有指针变量
class Person {
char *name;
int age;
public:
Person(char *n, int a) {
age = a;
name = new char[strlen(n) + 1];
strcpy(name, n);
}
Person(const Person &p) { // 复制构造函数
age = p.age;
name = new char[strlen(p.name) + 1];
strcpy(name, p.name);
}
void print() {
cout << "Name: " << name << ", Age: " << age << endl;
}
~Person() {
delete[] name;
}
};
int main() {
Person p1("John", 20);
Person p2 = p1; // 复制构造函数被调用
p1.print(); // 输出: Name: John, Age: 20
p2.print(); // 输出: Name: John, Age: 20
return 0;
}
上述代码中,我们定义了一个Person类,它有一个带参数的构造函数和一个复制构造函数。name是一个指针变量,使用new来动态分配内存。析构函数用来删除分配的内存。
复制构造函数是用来创建另一个Person对象,并且使用当前对象的值来初始化。使用new来分配内存,以确保在新对象的生命周期之外,指针变量不会被删除。