C++简明教程(10)(初识类)
类的教程
C++ 类的完整教程
C++ 中,类(class)是面向对象编程的核心概念,用于定义对象的属性(数据成员)和行为(成员函数)。本教程将带你从零开始,循序渐进地学习如何定义和使用类。
1. 类的基本定义
类类似于结构体(struct),但功能更加强大。以下是类的基本定义方法:
#include <iostream>
using namespace std;
class Person {
public: // 公有访问修饰符
string name; // 数据成员
int age;
void introduce() { // 成员函数
cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;
}
};
注意事项
- 类中可以包含数据成员和成员函数。
class
定义的成员默认是private
,而struct
定义的成员默认是public
。
2. 类和对象
类是模板或蓝图,而对象是基于类创建的具体实例。
int main() {
Person p; // 创建对象
p.name = "Alice";
p.age = 25;
p.introduce(); // 调用成员函数
return 0;
}
运行结果:
Hello, my name is Alice and I am 25 years old.
3. 访问修饰符:public
, private
, protected
访问修饰符控制类成员的访问权限:
public
: 公有成员,可被外部访问。private
: 私有成员,仅类内部可以访问。protected
: 保护成员,通常与继承相关,本教程中不讨论。
示例:
class Person {
private:
string secret; // 私有成员
public:
string name; // 公有成员
void setSecret(string s) { // 公有函数
secret = s;
}
void showSecret() {
cout << "Secret: " << secret << endl;
}
};
int main() {
Person p;
p.name = "Bob";
p.setSecret("I love coding."); // 使用公有函数访问私有成员
p.showSecret();
return 0;
}
运行结果:
Secret: I love coding.
注意事项
- 尽量将数据成员声明为
private
,通过公有函数访问。 - 保护数据成员可以提高代码的安全性。
4. 构造函数
构造函数用于在创建对象时初始化数据成员。它的名字与类名相同,无返回值。
示例代码
class Person {
public:
string name;
int age;
// 构造函数
Person(string n, int a) {
name = n;
age = a;
}
void introduce() {
cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;
}
};
int main() {
Person p("Charlie", 30); // 调用构造函数
p.introduce();
return 0;
}
运行结果:
Hello, my name is Charlie and I am 30 years old.
注意事项
- 构造函数没有返回值。
- 构造函数可以有多个参数。
5. 多种构造函数(构造函数重载)
可以定义多个构造函数以适应不同的初始化需求。
class Person {
public:
string name;
int age;
// 无参构造函数
Person() {
name = "Unknown";
age = 0;
}
// 带参构造函数
Person(string n, int a) {
name = n;
age = a;
}
void introduce() {
cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;
}
};
int main() {
Person p1; // 调用无参构造函数
Person p2("David", 40); // 调用带参构造函数
p1.introduce();
p2.introduce();
return 0;
}
运行结果:
Hello, my name is Unknown and I am 0 years old.
Hello, my name is David and I am 40 years old.
6. 析构函数
析构函数用于销毁对象时执行清理操作。名字为 ~类名()
,无参数和返回值。
class Person {
public:
Person() {
cout << "Constructor called." << endl;
}
~Person() {
cout << "Destructor called." << endl;
}
};
int main() {
Person p;
return 0;
}
运行结果:
Constructor called.
Destructor called.
注意事项
- 析构函数在对象生命周期结束时自动调用。
- 通常用于释放资源(如动态内存、文件等)。
7. 拷贝构造函数
拷贝构造函数用于用一个对象初始化另一个对象。
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;
cout << "Copy constructor called." << endl;
}
void introduce() {
cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;
}
};
int main() {
Person p1("Eve", 35);
Person p2 = p1; // 调用拷贝构造函数
p2.introduce();
return 0;
}
运行结果:
Copy constructor called.
Hello, my name is Eve and I am 35 years old.
好的,我们继续完成本教程!
8. 运算符重载
运算符重载允许我们为类定义如何使用运算符(如 =
、<
等)。接下来我们将学习如何重载等号(=
)和小于号(<
)。
重载等号运算符(=
)
等号运算符通常用于赋值操作,我们需要重载它以确保正确复制对象的内容。
class Person {
private:
string name;
int age;
public:
// 构造函数
Person(string n, int a) : name(n), age(a) {}
// 重载等号运算符
Person& operator=(const Person& p) {
if (this == &p) {
return *this; // 检查是否是自我赋值
}
name = p.name;
age = p.age;
cout << "Assignment operator called." << endl;
return *this;
}
void introduce() {
cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;
}
};
int main() {
Person p1("Alice", 25);
Person p2("Bob", 30);
p2 = p1; // 调用赋值运算符
p2.introduce();
return 0;
}
运行结果:
Assignment operator called.
Hello, my name is Alice and I am 25 years old.
重载小于号运算符(<
)
通常用于比较对象。例如,比较两个对象的某个属性。
class Person {
public:
string name;
int age;
// 构造函数
Person(string n, int a) : name(n), age(a) {}
// 重载小于号运算符
bool operator<(const Person& p) const {
return age < p.age; // 按年龄比较
}
};
int main() {
Person p1("Alice", 25);
Person p2("Bob", 30);
if (p1 < p2) {
cout << p1.name << " is younger than " << p2.name << "." << endl;
} else {
cout << p1.name << " is not younger than " << p2.name << "." << endl;
}
return 0;
}
运行结果:
Alice is younger than Bob.
9. 成员函数
成员函数是定义在类中的函数,用于操作数据成员。分为 公有成员函数 和 私有成员函数。
公有成员函数
公有成员函数可以被类外部调用。
class Person {
public:
string name;
void introduce() { // 公有成员函数
cout << "My name is " << name << "." << endl;
}
};
私有成员函数
私有成员函数只能在类内部调用。
class Person {
private:
void privateFunction() {
cout << "This is a private function." << endl;
}
public:
void callPrivateFunction() {
privateFunction(); // 内部调用私有函数
}
};
int main() {
Person p;
p.callPrivateFunction();
return 0;
}
运行结果:
This is a private function.
10. 静态函数与静态数据成员
静态数据成员
静态数据成员是类的所有对象共享的变量。
class Person {
public:
static int population; // 静态数据成员
Person() {
population++;
}
~Person() {
population--;
}
static void showPopulation() { // 静态成员函数
cout << "Current population: " << population << endl;
}
};
// 静态数据成员初始化
int Person::population = 0;
int main() {
Person::showPopulation(); // 访问静态成员函数
Person p1, p2;
Person::showPopulation();
return 0;
}
运行结果:
Current population: 0
Current population: 2
注意事项
- 静态数据成员需要在类外初始化。
- 静态成员函数只能访问静态数据成员。
11. this
指针
this
指针指向当前对象,用于区分成员变量与形参重名的情况。
class Person {
private:
string name;
public:
void setName(string name) {
this->name = name; // 使用 this 指针区分成员变量和参数
}
void introduce() {
cout << "My name is " << this->name << "." << endl;
}
};
int main() {
Person p;
p.setName("Alice");
p.introduce();
return 0;
}
运行结果:
My name is Alice.
12. 总结与注意事项
- 类是一种封装机制,通过访问修饰符控制成员访问权限。
- 构造函数和析构函数用于管理对象生命周期,特别是动态分配资源时。
- 运算符重载使对象更具灵活性,但需要小心处理自我赋值。
- 静态成员共享数据,对整个类有效。
this
指针是成员函数内部隐含的指针,指向当前对象。