📅  最后修改于: 2023-12-03 15:29:42.463000             🧑  作者: Mango
在 C++ 中,构造函数是一种特殊的成员函数,用于在对象被创建时初始化对象的数据成员。本文将介绍 C++ 中的构造函数以及一些常见的问题。
构造函数是与类同名的特殊成员函数,没有返回类型,不用显式调用,当对象被创建时自动调用。构造函数的作用是初始化对象的数据成员,保证对象的状态是有效的。
class Person {
public:
Person() {
name = "";
age = 0;
}
Person(string n, int a) {
name = n;
age = a;
}
private:
string name;
int age;
};
int main() {
Person p1; // 调用无参构造函数
Person p2("Bob", 21); // 调用有参构造函数
return 0;
}
在上面示例中,我们定义了一个 Person
类,它包含一个默认的无参构造函数和一个带参构造函数。当我们创建 Person
类的对象时,构造函数会自动调用,初始化 name
和 age
数据成员。
如果没有显式定义构造函数,则编译器会为类自动生成默认构造函数。默认构造函数无参,没有函数体,只是简单地初始化所有数据成员的值。如果类中没有数据成员,则默认构造函数是空的。
class Point {
public:
Point(); // 默认构造函数,如果不定义,编译器会自动生成一个
private:
int x, y;
};
Point::Point() {
x = y = 0;
}
int main() {
Point p; // 调用默认构造函数
return 0;
}
拷贝构造函数是一种特殊的构造函数,它的参数是一个对象的引用,用于将一个对象的值拷贝到另一个对象中。当我们对一个对象进行拷贝构造时,会调用该对象的拷贝构造函数。
class String {
public:
String(const String& s) {
len = s.len;
str = new char[len];
strcpy(str, s.str);
}
private:
int len;
char* str;
};
int main() {
String s1("hello");
String s2(s1); // 调用拷贝构造函数
return 0;
}
带参构造函数是指具有参数的构造函数,用于在创建对象时初始化数据成员的值。通过使用带参构造函数,我们可以灵活地创建不同状态的对象。
class Rectangle {
public:
Rectangle(int w, int h) {
width = w;
height = h;
}
private:
int width, height;
};
int main() {
Rectangle r1(10, 20); // 调用带参构造函数
Rectangle r2 = Rectangle(30, 40); // 等价于上一句
return 0;
}
在一些特殊情况下,C++ 会隐式调用构造函数。例如,当我们用一个类对象初始化一个新的对象时,会隐式调用拷贝构造函数。当我们用一个类对象作为函数参数传递给另一个函数时,也会隐式调用拷贝构造函数。
Point p(1, 2);
Point q = p; // 隐式调用拷贝构造函数
void func(Point p); // 声明函数
func(p); // 隐式调用拷贝构造函数
默认构造函数是没有参数的构造函数,而无参构造函数是指没有参数并且没有函数体的构造函数。默认构造函数可以由编译器自动生成,而无参构造函数必须显式定义。如果我们同时定义了默认构造函数和无参构造函数,则编译器会优先调用无参构造函数。
class Person {
public:
Person(); // 无参构造函数
private:
string name;
int age;
};
Person::Person() {
name = "";
age = 0;
}
int main() {
Person p1; // 调用无参构造函数
Person p2(); // 声明一个函数,而非调用无参构造函数
return 0;
}
如果一个类有多个构造函数,它们之间的区别在于它们的参数列表不同。当我们创建一个对象时,编译器会根据参数列表来确定调用哪个构造函数。如果我们没有指定参数,则会调用默认构造函数或无参构造函数。
class Person {
public:
Person(); // 无参构造函数
Person(string n, int a); // 带参构造函数
private:
string name;
int age;
};
Person::Person() {
name = "";
age = 0;
}
Person::Person(string n, int a) {
name = n;
age = a;
}
int main() {
Person p1; // 调用无参构造函数
Person p2("Bob", 21); // 调用带参构造函数
return 0;
}
构造函数不能被继承,但是派生类可以调用基类的构造函数来初始化基类的数据成员。如果派生类没有显式调用基类的构造函数,则会调用默认构造函数或者无参构造函数。
class Animal {
public:
Animal(string n) {
name = n;
}
private:
string name;
};
class Cat : public Animal {
public:
Cat(string n, int a) : Animal(n) { // 调用基类的构造函数
age = a;
}
private:
int age;
};
int main() {
Cat c("Tom", 3);
return 0;
}