文章目录
- 一、对象的创建
- 1.1 定义类
- 1.2 创建对象
- 二、对象的初始化
- 2.1 默认构造函数
- 2.2 带参数的构造函数
- 2.3 初始化列表
- 三、拷贝构造函数
- 四、对象的销毁
- 五、总结
- 视频讲解笔记
- 在栈上创建
- 在堆上创建
- new
在C++中,创建并初始化对象是面向对象编程(OOP)的核心操作之一。对象的创建与初始化主要通过类和构造函数来完成。以下是关于C++中对象的创建和初始化的详细教学。
一、对象的创建
1.1 定义类
在创建对象之前,首先需要定义一个类。类是对象的蓝图,定义了对象的属性和行为。类通常包含成员变量(属性)和成员函数(方法)。
示例:
class Person {
public:
string name;
int age;
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
在这个示例中,Person
类包含两个成员变量name
和age
,以及一个成员函数display()
用于显示对象的信息。
1.2 创建对象
创建对象的过程称为“实例化”。实例化是指通过类的定义创建一个类的对象。对象的创建可以在栈上或堆上进行。
栈上创建对象:
int main() {
Person p1; // 创建一个 Person 对象
p1.name = "John";
p1.age = 30;
p1.display(); // 输出: Name: John, Age: 30
return 0;
}
堆上创建对象:
int main() {
Person* p2 = new Person; // 在堆上创建一个 Person 对象
p2->name = "Alice";
p2->age = 25;
p2->display(); // 输出: Name: Alice, Age: 25
delete p2; // 手动释放堆上的内存
return 0;
}
在栈上创建的对象在作用域结束时自动销毁,而在堆上创建的对象则需要手动释放内存。
二、对象的初始化
对象的初始化可以通过构造函数来实现。构造函数是类的一种特殊成员函数,用于在对象创建时对其进行初始化。
2.1 默认构造函数
如果类中没有显式定义构造函数,编译器会自动生成一个默认构造函数。默认构造函数不接受参数,通常用于简单的对象初始化。
示例:
class Person {
public:
string name;
int age;
Person() {
name = "Unknown";
age = 0;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Person p1; // 调用默认构造函数
p1.display(); // 输出: Name: Unknown, Age: 0
return 0;
}
在这个示例中,Person
类定义了一个默认构造函数,该构造函数将name
初始化为"Unknown"
,将age
初始化为0
。
2.2 带参数的构造函数
带参数的构造函数允许在创建对象时传递参数,以便对对象进行更灵活的初始化。
示例:
class Person {
public:
string name;
int age;
Person(string n, int a) {
name = n;
age = a;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Person p1("John", 30); // 调用带参数的构造函数
p1.display(); // 输出: Name: John, Age: 30
return 0;
}
在这个示例中,Person
类的构造函数接受两个参数,并将它们用于初始化name
和age
。
2.3 初始化列表
C++提供了初始化列表(Initializer List),用于在构造函数中直接初始化成员变量。初始化列表比在构造函数体内进行赋值更高效,尤其对于常量成员和引用成员来说是唯一的初始化方式。
示例:
class Person {
public:
string name;
int age;
Person(string n, int a) : name(n), age(a) {} // 使用初始化列表
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Person p1("Alice", 25);
p1.display(); // 输出: Name: Alice, Age: 25
return 0;
}
在这个示例中,Person
类的构造函数使用了初始化列表,这样做不仅简洁,而且避免了在构造函数体内进行额外的赋值操作。
三、拷贝构造函数
当一个对象被用作另一个对象的初始值或被传递给函数时,会调用拷贝构造函数。拷贝构造函数用于创建对象的副本。
示例:
class Person {
public:
string name;
int age;
Person(string n, int a) : name(n), age(a) {}
// 拷贝构造函数
Person(const Person &p) {
name = p.name;
age = p.age;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Person p1("John", 30);
Person p2 = p1; // 调用拷贝构造函数
p2.display(); // 输出: Name: John, Age: 30
return 0;
}
在这个示例中,Person
类定义了一个拷贝构造函数。当创建对象p2
时,调用拷贝构造函数将p1
的值复制给p2
。
四、对象的销毁
对象的销毁是由析构函数完成的。析构函数用于释放对象在生存期内分配的资源。析构函数是一个没有返回值、没有参数、名称与类名相同并前置~
符号的特殊成员函数。
示例:
class Person {
public:
string name;
int age;
Person(string n, int a) : name(n), age(a) {}
~Person() {
cout << name << " is being destroyed" << endl;
}
};
int main() {
Person p1("John", 30);
return 0; // 当 p1 超出作用域时,自动调用析构函数
}
在这个示例中,当p1
超出作用域时,自动调用析构函数,输出信息表明对象正在被销毁。
五、总结
- 对象的创建:可以在栈上或堆上创建对象,通过类的定义实例化对象。
- 对象的初始化:主要通过构造函数完成,包括默认构造函数、带参数的构造函数和使用初始化列表。
- 拷贝构造函数:用于创建对象的副本,在需要复制对象时调用。
- 对象的销毁:由析构函数完成,用于释放资源。
掌握对象的创建和初始化是理解和使用C++面向对象编程的基础。通过合理地设计构造函数和析构函数,可以有效地管理对象的生命周期和资源的使用。
视频讲解笔记
创建并初始化C++ 对象,有两种方式:
1、如果你想手动控制它的创建和释放,以及需要的内存比较大,就在堆上创建,使用new,对应的需要delete,否则会出现内存泄漏;
2、栈上一般1–2M的内存,比较小,当时性能比堆上快,会在自己的作用域结束后自动释放。
在栈上创建
默认构造函数,已经初始化,不会有空指针异常。
在堆上创建
new
new,寻找一块连续的内存,然后把地址返回,所以创建时是:
Entity *e = new Entity();
寻找连续的地址也是根据空闲列表寻找,并不是逐行遍历那么笨拙;