目录
第1章 C++类的基础
在C++编程中,类是一个核心概念,它是面向对象编程的基础。本章将全面介绍类的基本概念,帮助您深入理解和熟练使用C++类。
1.1 类的概念和作用
类是C++中用于创建用户自定义类型的工具。它是一种将数据和操作数据的函数封装在一起的方法。类可以看作是一个蓝图或模板,用于创建具有相同属性和行为的对象。
什么是类
类是一种用户自定义的数据类型,它定义了一组属性(数据成员)和方法(成员函数)。例如,我们可以定义一个"Car"类:
class Car {
private:
string brand;
string model;
int year;
public:
void setBrand(string b) { brand = b; }
void setModel(string m) { model = m; }
void setYear(int y) { year = y; }
void displayInfo() {
cout << year << " " << brand << " " << model << endl;
}
};
在这个例子中,Car类有三个私有数据成员(brand, model, year)和四个公有成员函数(setBrand, setModel, setYear, displayInfo)。
类和对象的关系
类是一个抽象的概念,而对象是类的具体实例。如果类是蓝图,那么对象就是根据这个蓝图建造的实际房子。例如:
Car myCar; // 创建一个Car类的对象
myCar.setBrand("Toyota");
myCar.setModel("Corolla");
myCar.setYear(2022);
myCar.displayInfo(); // 输出: 2022 Toyota Corolla
类的优势和应用场景
类提供了多项优势:
- 封装: 将数据和操作数据的函数绑定在一起,提高了代码的安全性和可维护性。类可以隐藏其内部实现细节,只向外部提供必要的接口。
- 抽象: 允许隐藏复杂的实现细节,只暴露必要的接口。这使得使用类的代码更加简洁和易于理解。
- 重用: 类定义一次,可以创建多个对象,促进代码重用。这大大提高了开发效率和代码的可维护性。
- 组织: 帮助更好地组织和结构化代码。类提供了一种将相关的数据和函数组织在一起的方式,使代码结构更清晰。
- 继承: 类支持继承机制,允许创建层次结构和共享代码,进一步提高了代码重用性。
- 多态: 通过类的多态性,可以实现更灵活和可扩展的代码设计。
应用场景:
- 对象建模: 在开发过程中,类常用于对现实世界的对象进行建模。例如,在一个银行系统中,可以创建Account, Customer, Transaction等类。
- 数据抽象: 当需要创建复杂的数据结构时,类提供了一种理想的方式来封装数据和相关的操作。
- 库和框架开发: 许多C++库和框架都大量使用类来提供功能和抽象。
- 图形用户界面(GUI)编程: 在GUI编程中,类通常用于表示窗口、按钮、菜单等界面元素。
- 游戏开发: 在游戏开发中,类可以用来表示游戏中的实体,如角色、道具、场景等。
1.2 类的定义和声明
类的定义是创建新类型的过程,而声明则是告诉编译器某个类的存在。让我们详细探讨类的定义和声明。
类的基本语法
类的基本语法如下:
class ClassName {
// 访问说明符
public:
// 公有成员
protected:
// 保护成员
private:
// 私有成员
};
例如,一个简单的Person类可能如下所示:
class Person {
public:
void setName(string n) { name = n; }
string getName() { return name; }
private:
string name;
int age;
};
成员变量和成员函数
- 成员变量(也称为数据成员):
成员变量是在类中定义的变量。它们代表了类的属性或状态。在上面的Person类中,name和age就是成员变量。 - 成员函数(也称为方法):
成员函数是在类中定义的函数。它们定义了类的行为。在Person类中,setName和getName是成员函数。
成员函数可以在类定义内部直接定义,也可以在类外部定义:
class Rectangle {
public:
void setWidth(int w);
void setHeight(int h);
int getArea();
private:
int width;
int height;
};
// 在类外部定义成员函数
void Rectangle::setWidth(int w) {
width = w;
}
void Rectangle::setHeight(int h) {
height = h;
}
int Rectangle::getArea() {
return width * height;
}
公有、私有和保护访问修饰符
C++提供了三种访问修饰符来控制类成员的访问权限:
- public: 公有成员可以被任何代码访问。
- private: 私有成员只能被类的成员函数访问。
- protected: 保护成员可以被类的成员函数和派生类访问。
例如:
class MyClass {
public:
int publicVar;
void publicFunction() {}
protected:
int protectedVar;
void protectedFunction() {}
private:
int privateVar;
void privateFunction() {}
};
在这个例子中:
- publicVar和publicFunction可以被任何代码访问。
- protectedVar和protectedFunction只能被MyClass的成员函数和派生类访问。
- privateVar和privateFunction只能被MyClass的成员函数访问。
使用这些访问修饰符可以实现封装,控制对类成员的访问,提高代码的安全性和可维护性。
1.3 对象的创建和使用
对象是类的实例。创建和使用对象是面向对象编程的核心。让我们详细探讨如何创建和使用C++对象。
对象的实例化
有几种方式可以创建类的对象:
1.栈上创建:
ClassName objectName;
Person person1;
2.堆上创建(使用new关键字):
ClassName* ptrObject = new ClassName();
Person* pPerson = new Person();
3.使用构造函数初始化:
ClassName objectName(arg1, arg2, ...);
Person person2("John", 30);
访问对象的成员
可以使用点运算符(.)访问栈上创建的对象的成员,使用箭头运算符(->)访问通过指针引用的对象的成员:
person1.setName("Alice");
cout << person1.getName() << endl;
pPerson->setName("Bob");
cout << pPerson->getName() << endl;
对象数组
可以创建类对象的数组:
Person people[3]; // 创建包含3个Person对象的数组
// 或者动态分配
Person* pPeople = new Person[3];
// 使用数组
people[0].setName("Alice");
people[1].setName("Bob");
people[2].setName("Charlie");
// 记得删除动态分配的数组
delete[] pPeople;
使用对象数组时,要注意:
- 如果类没有默认构造函数,你需要为每个数组元素调用适当的构造函数。
- 对于动态分配的对象数组,必须使用delete[]来释放内存。
1.4 构造函数和析构函数
构造函数和析构函数是特殊的成员函数,用于初始化和清理对象。
默认构造函数
默认构造函数是不带参数的构造函数。如果没有定义任何构造函数,编译器会提供一个默认构造函数。
class MyClass {
public:
MyClass() {
// 初始化代码
}
};
带参数的构造函数
带参数的构造函数允许在创建对象时初始化其成员:
class Person {
public:
Person(string n, int a) : name(n), age(a) {}
private:
string name;
int age;
};
// 使用
Person p("Alice", 30);
析构函数
析构函数在对象被销毁时自动调用,用于清理资源:
构造函数重载
可以定义多个构造函数,每个具有不同的参数列表:
class Rectangle {
public:
Rectangle() : width(0), height(0) {}
Rectangle(int w, int h) : width(w), height(h) {}
Rectangle(int size) : width(size), height(size) {}
private:
int width, height;
};
1.5 this指针
this指针是一个特殊的指针,它指向当前对象的地址。
this指针的概念
- 每个成员函数都有一个隐含的this指针,指向调用该函数的对象。
- this是一个常量指针,不能被修改。
- 在成员函数内部,可以使用this来访问当前对象的成员。
this指针的使用场景
1.区分同名的参数和成员变量:
class Person {
public:
void setName(string name) {
this->name = name; // 使用this区分参数和成员变量
}
private:
string name;
};
2.返回对象自身的引用:
class Counter {
public:
Counter& increment() {
count++;
return *this; // 返回对象自身
}
private:
int count = 0;
};
// 使用
Counter c;
c.increment().increment().increment();
3.在构造函数中调用另一个构造函数(C++11及以后):
class MyClass {
public:
MyClass(int a) : x(a) {}
MyClass() : MyClass(0) {} // 委托构造函数
private:
int x;
};
通过深入理解和灵活运用这些基础概念,你将能够更好地设计和实现C++类,为面向对象编程打下坚实的基础。
第2章 类的进阶特性
在掌握了C++类的基础知识之后,我们将深入探讨一些更高级的特性。这些特性能够帮助你创建更加强大和灵活的类设计。
2.1 静态成员
静态成员是属于类本身而不是类的任何特定对象的成员。它们在类的所有对象之间共享。
静态成员变量
静态成员变量具有以下特点:
- 它们在类的所有实例之间共享一个副本。
- 它们必须在类外部定义和初始化(除非是const整型或枚举类型)。
- 它们可以通过类名直接访问,无需创建类的对象。
例如:
class MyClass {
public:
static int count;
MyClass() { count++; }
};
int MyClass::count = 0; // 在类外部定义和初始化
int main() {
MyClass obj1, obj2, obj3;
cout << "Number of objects created: " << MyClass::count << endl; // 输出 3
return 0;
}
静态成员的初始化和访问
静态成员的初始化通常在类定义外部进行:
class MyClass {
public:
static int staticVar;
static const int constStaticVar = 100; // const静态成员可以在类内初始化
};
int MyClass::staticVar = 0; // 非const静态成员在类
写不下去了......能讲的都讲完了,自己应用吧