提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、C和C++的区别
- 二、C++的灵魂——类
- 2.1 类的定义与成员
- 2.2 对象与实例化
- 2.3 面向对象的三大特性
- 2.4 运算符重载与友元函数
前言
C++是一种功能强大、灵活的编程语言,广泛应用于系统软件、应用软件、设备驱动、嵌入式软件、高性能服务器和客户端应用程序、游戏引擎等。
一、C和C++的区别
C 和 C++ 是两种广泛使用的编程语言,它们之间有许多区别。C++ 是在 C 的基础上发展而来的,增加了许多新特性和功能。以下是 C 和 C++ 之间的一些主要区别:
- 面向对象编程
C:是面向过程的编程语言,主要通过函数和过程进行编程。
C++:是面向对象的编程语言,支持类和对象。C++ 中的面向对象特性包括封装、继承和多态性。 - 数据抽象和封装
C:没有直接支持数据抽象和封装的语言特性,程序员需要通过结构体和函数进行模拟。
C++:引入了类和对象,通过访问控制符(public、private、protected)实现数据抽象和封装。 - 继承
C:不支持继承,无法通过一个类继承另一个类的属性和方法。
C++:支持继承,可以通过基类和派生类的关系重用代码。 - 多态性
C:不支持多态性,函数重载和运算符重载也不支持。
C++:支持多态性,包括函数重载和运算符重载,以及通过虚函数实现的动态多态性。 - 标准库
C:C 标准库提供了有限的函数,如 stdio.h、stdlib.h 等。
C++:C++ 标准库不仅包含 C 标准库的所有功能,还增加了如 STL(标准模板库),包括容器、迭代器和算法等。 - 内存管理
C:内存管理主要通过 malloc、calloc 和 free 等函数进行。
C++:内存管理可以通过 new 和 delete 操作符进行,此外还支持智能指针(如 std::unique_ptr 和 std::shared_ptr)来自动管理内存。 - 输入输出
C:使用标准的输入输出库函数,如 printf 和 scanf。
C++:使用更高级的 I/O 流库,如 cin 和 cout,支持类型安全和操作符重载。 - 函数和参数
C:函数参数不能有默认值。
C++:函数参数可以有默认值,支持更灵活的函数调用。 - 命名空间
C:没有命名空间,所有标识符共享一个全局命名空间,容易发生命名冲突。
C++:引入了命名空间,通过 namespace 关键字定义命名空间,避免命名冲突。 - 模板
C:不支持模板。
C++:支持模板,可以编写泛型代码,进行代码复用,如模板函数和模板类。 - 异常处理
C:不支持异常处理,错误处理通常通过返回值和错误代码进行。
C++:支持异常处理,通过 try、catch 和 throw 关键字处理异常。 - 兼容性
C:是 C++ 的子集,大部分 C 代码可以在 C++ 编译器下编译,但并非所有 C++ 代码都能在 C 编译器下编译。
C++:可以包含 C 代码并进行编译,但需要注意一些语法和特性的区别。
二、C++的灵魂——类
类(Class)可以被称为这门语言的“灵魂”,因为它不仅是面向对象编程(OOP)的核心,也是实现代码重用、模块化和抽象的关键。我们可以把类看作是c语言中结构体的升级版,它可以既可以包含变量,也可以包含函数(我们再leecode刷的题就是在进行类的编写)。
2.1 类的定义与成员
类是用户自定义的数据类型,由数据成员(attributes)和函数成员(methods)组成。类的定义包括类的名称、数据成员以及成员函数的声明与定义。C++中的类有三种访问控制方式:public、protected和private。这决定了类的成员在类外部的可访问性。
- public:所有成员可以在类外部直接访问。
- private:成员只能在类内部访问,类的外部不能直接访问这些成员。默认情况下,类的成员是private。
- protected:成员只能在类内部或派生类中访问,但不能在类的外部直接访问。
在C++中,类的成员可以分为几种不同的类型,每种类型都有其独特的用途和特性。了解这些成员类型有助于更灵活地设计和实现类。
- 数据成员(Data Members)是类中定义的变量,用于存储类对象的状态或属性。根据访问控制级别,它们可以是公有、私有或受保护的。
- 实例数据成员:这些是为每个对象单独存储的变量。每个对象都有自己的一份数据成员的副本。
- 静态数据成员:静态数据成员在所有对象之间共享,属于整个类而非某个对象。它们在类的定义中声明,并在类外部定义和初始化。
- 成员函数(Member Functions)是操作类对象的函数。根据它们的访问控制级别,它们也可以是公有、私有或受保护的。
- 实例成员函数:实例成员函数是操作类对象的普通函数。它们可以访问类的所有数据成员,包括私有数据成员。
- 静态成员函数:静态成员函数只能访问静态数据成员和其他静态成员函数,因为它们不依赖于具体的对象。静态成员函数通过类名调用,而不是通过对象调用。
- 内联函数(Inline Functions):内联函数是一种建议编译器将函数代码嵌入到调用点以减少函数调用开销的成员函数。这通常用于小型、频繁调用的函数。
- 构造函数:构造函数是类的特殊成员函数,用于初始化对象。构造函数在创建对象时(实例化时)自动调用,名称与类名相同。
- 析构函数:析构函数是在对象生命周期结束时自动调用的特殊成员函数,用于清理资源。它的名称与类名相同,但前面带有波浪号~,没有返回类型和参数。
- 常量成员(Const Members)指的是类中的常量数据成员和常量成员函数。
- 常量数据成员:一旦初始化后,其值不能再修改。它们必须通过初始化列表进行初始化。
- 常量成员函数:这些函数在调用过程中不会修改对象的状态,即不会修改任何数据成员。它们必须使用const关键字修饰。
// 示例:定义一个类
class ClassName {
public:// 公有成员int publicDataMember;void publicMemberFunction(){...}private:// 私有成员int privateDataMember;void privateMemberFunction(){...}protected:// 受保护成员int protectedDataMember;void protectedMemberFunction(){...}
};
2.2 对象与实例化
类的实例称为对象。通过类定义可以创建多个对象,每个对象都有独立的属性空间,但共享类的成员函数。通过类来创建对象的过程称为实例化。可以使用构造函数来初始化对象的成员变量。
// 直接定义
ClassName test; // ClassName表示类,test表示对象
// 在堆里定义
ClassName* test = new ClassName;
// 删除对象(用于在堆里定义的方法)
delete test;
2.3 面向对象的三大特性
封装(Encapsulation):将数据与操作数据的函数捆绑在一起,并隐藏对象的内部实现细节,只对外暴露接口。这增强了代码的安全性和可维护性。
多态(Polymorphism):允许使用基类的指针或引用来调用派生类的方法。在运行时,C++会根据实际的对象类型来调用合适的方法,这被称为动态绑定或运行时多态。
继承(Inheritance):类的继承是C++面向对象编程的核心特性之一,它允许一个类(子类或派生类)从另一个类(父类或基类)继承数据成员和成员函数,从而实现代码的重用和扩展。继承还支持多态性,使得子类对象可以被当作基类对象来使用。基类也称为父类或超类,是被继承的类;与之相对的派生类称为子类,是继承基类的类,派生类继承了基类的所有数据成员和成员函数。继承通过在派生类的声明中指定基类来实现。语法如下:
class BaseClass {// 基类的成员
};/* accessSpecifier:用于指定基类成员在派生类中的访问权限,可以是public、protected或private。*/
class DerivedClass : accessSpecifier BaseClass {// 派生类的成员
};
C++支持三种主要的继承方式,它们分别控制了基类成员在派生类中的访问级别——accessSpecifier:
- 公有继承(Public Inheritance):基类的public成员在派生类中保持public,protected成员保持protected,private成员仍然无法访问。
- 保护继承(Protected Inheritance):基类的public和protected成员在派生类中都变成protected,private成员仍然无法访问。
- 私有继承(Private Inheritance):基类的public和protected成员在派生类中都变成private,private成员仍然无法访问。
2.4 运算符重载与友元函数
运算符重载:C++允许重载运算符,使之能够作用于用户自定义的类型。通过重载运算符,可以实现类的对象之间更自然的操作方式。我们可以在类中定义同名的函数,但是他们的参数不能相同,在调用的时候会根据具体的参数进行相应的匹配。
友元函数:友元函数不是类的成员,但它可以访问类的私有成员。友元关系是单向的,友元函数往往用于操作多个类的私有数据或重载特定运算符。