零食网站色调搭配怎麽做,申远空间设计公司,衡水网站设计公司哪家好,国有资产处网站建设C(10)之类语法分析(1) Author: Once Day Date: 2024年8月17日 一位热衷于Linux学习和开发的菜鸟#xff0c;试图谱写一场冒险之旅#xff0c;也许终点只是一场白日梦… 漫漫长路#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: 源码分析_Once-Day的博客-CSDN博客 … C(10)之类语法分析(1) Author: Once Day Date: 2024年8月17日 一位热衷于Linux学习和开发的菜鸟试图谱写一场冒险之旅也许终点只是一场白日梦… 漫漫长路有人对你微笑过嘛… 全系列文章可参考专栏: 源码分析_Once-Day的博客-CSDN博客 参考文章: 【C】类的概念与基本使用介绍-CSDN博客C 类 对象 | 菜鸟教程 (runoob.com)C从入门到精通——类的定义及类的访问限定符和封装-腾讯云开发者社区-腾讯云 (tencent.com)类和结构 (C) | Microsoft LearnC 类 对象_w3cschoolC打怪升级四- 类和对象入门1-腾讯云开发者社区-腾讯云 (tencent.com) 文章目录 C(10)之类语法分析(1)1. 介绍1.1 概述1.2 类基本概念1.3 类、结构体和联合的联系和区别 2. 类基础特性2.1 类成员函数2.2 类成员内联函数2.3 构造函数和析构函数2.4 列表初始化(c11)2.5 const成员函数2.6 类作用域和静态成员2.7 this指针 1. 介绍
1.1 概述
在C中类(Class)是一种用户自定义的数据类型它将数据成员(属性)和成员函数(方法)组合在一起形成一个逻辑上相关的实体。通过使用类我们可以创建出具有特定行为和状态的对象。
类的定义通常包含以下几个部分: 类名类的名称。通常以大写字母开头使用驼峰命名法。 访问修饰符控制类的成员对外部的可见性包括public(公有)、protected(保护)和private(私有)三种。 数据成员类的属性描述了类的状态。可以是基本数据类型、数组、指针、对象等。 成员函数类的方法定义了类的行为。包括构造函数、析构函数、普通成员函数等。
下面是一个简单的类定义示例:
class Student {
private:string name;int age;public:Student(string n, int a) {name n;age a;}void displayInfo() {cout Name: name endl;cout Age: age endl;}
};在这个例子中定义了一个名为Student的类。它有两个私有数据成员name和age分别表示学生的姓名和年龄。同时它还有两个公有成员函数构造函数Student()用于初始化对象displayInfo()用于显示学生的信息。
创建类的对象很简单只需要使用类名和构造函数即可:
Student stu(Alice, 20);
stu.displayInfo();以上代码创建了一个名为stu的Student对象并调用其displayInfo()方法输出学生信息。
1.2 类基本概念
类(class)类是一个用户定义的数据类型它包含数据成员属性和成员函数方法。
抽象(Abstraction)抽象是指将对象的共同特征抽取出来形成一个类的过程。它强调了对象的本质属性和行为而忽略了非本质的细节。通过抽象我们可以创建出更加通用和灵活的类。
继承(Inheritance)继承是一种类与类之间的关系它允许一个类(子类)继承另一个类(父类或基类)的属性和方法。通过继承子类可以重用父类的代码并可以添加或修改自己特有的功能。继承提高了代码的复用性和可维护性。
多态(Polymorphism)多态是指同一操作作用于不同的对象可以有不同的解释产生不同的执行结果。在C中多态分为静态多态(函数重载)和动态多态(虚函数)。多态提供了一种接口重用的方式增强了程序的可扩展性。
成员(Member)成员是属于类的一部分包括数据成员(属性)和成员函数(方法)。数据成员用于描述类的状态成员函数用于定义类的行为。成员可以是静态的(属于类本身)或非静态的(属于类的对象)。
访问修饰符(Access Modifiers)访问修饰符用于控制类的成员对外部的可见性包括以下三种:
public(公有)公有成员可以被任何地方访问包括类的内部和外部。protected(保护)保护成员可以被类自身及其子类访问但不能被类的外部直接访问。private(私有)私有成员只能被类自身访问不能被子类和类的外部访问。
1.3 类、结构体和联合的联系和区别
结构(struct)、类(class)和联合(union)是C中三种重要的用户自定义数据类型结构和类的主要区别在于默认的访问修饰符不同结构默认是公有的类默认是私有的。
结构和类都支持面向对象编程的特性如封装、继承、多态等。但在实践中结构更倾向于被用作简单的数据容器而类更倾向于被用于定义复杂的数据类型和行为。
联合与结构和类的区别较大。联合强调了成员之间的互斥性同一时间只能存储一个成员的值常用于节省内存空间或者表示变体类型。
特性结构(struct)类(class)联合(union)默认访问修饰符publicprivate无(所有成员公有)访问修饰符支持支持public、protected、private支持public、protected、private不支持数据成员支持支持支持成员函数支持支持不支持构造函数/析构函数支持支持不支持继承可以继承其他结构或类可以继承其他类或结构支持多重继承不支持继承多态不直接支持但可以通过继承实现支持可以定义虚函数不支持内存布局每个成员独立占用内存空间每个成员独立占用内存空间所有成员共享同一块内存空间常见用途简单的数据容器定义复杂的数据类型和行为节省内存空间表示变体类型
2. 类基础特性
2.1 类成员函数
类成员函数是类的重要组成部分它们定义了类的行为和功能。
(1) 特殊成员函数是编译器自动生成或用户显式定义的一组函数包括:
默认构造函数无参数或所有参数都有默认值的构造函数。析构函数在对象销毁时自动调用用于释放资源。拷贝构造函数使用另一个同类型对象初始化当前对象。移动构造函数使用另一个同类型的右值对象初始化当前对象。拷贝赋值运算符将另一个同类型对象赋值给当前对象。移动赋值运算符将另一个同类型的右值对象赋值给当前对象。
(2) 可变和静态数据成员:
可变数据成员使用mutable关键字声明即使在常量对象中也可以被修改。静态数据成员使用static关键字声明属于类本身而不是类的实例静态数据成员在类外部初始化。
(3) 内置类型和用户定义类型类的数据成员可以是内置类型(如int、double等)或其他用户定义的类型(如类、结构体等)。对于用户定义类型的数据成员需要注意初始化的顺序和方式。
(4) 运算符类可以重载运算符以提供特定于类的操作。重载运算符的函数可以是类的成员函数或友元函数。
(5) 嵌套类声明类可以在另一个类的内部声明,称为嵌套类。嵌套类可以访问外围类的私有成员。
(6) Unions类可以包含联合(Union)类型的数据成员。联合允许在同一内存位置存储不同类型的对象。
(7) 枚举类可以包含枚举(Enum)类型的数据成员。枚举用于定义一组命名的整型常量。
(8) 位域类可以包含位域(Bit Field)类型的数据成员。位域允许在一个整型变量中指定位的数量以节省内存空间。
(9) 友元类可以将其他类、函数或模板声明为友元(Friend)以允许它们访问类的私有成员。
(10) 别名和typedef类可以使用别名(如using关键字)或typedef为类型定义新的名称以提高代码的可读性。
在构造函数中可以使用初始化列表来初始化数据成员特别是const成员和引用成员。如果数据成员没有在构造函数中显式初始化则会进行默认初始化。内置类型的默认初始化值取决于数据成员的存储位置。静态数据成员在类外部初始化而不是在构造函数中初始化。
2.2 类成员内联函数
类成员函数和内联函数有着紧密的联系合理地使用内联成员函数可以提高程序的执行效率。 内联函数是一种特殊的函数它的函数体在编译时被直接插入到调用点而不是像普通函数那样通过函数调用和返回的方式执行。这样可以避免函数调用的开销提高程序的执行效率。内联函数通常适用于短小、频繁调用的函数。 类成员函数(Class Member Function)类成员函数是属于类的一部分用于定义类的行为。成员函数可以访问类的私有成员并且可以被类的对象调用。成员函数可以是普通函数也可以是内联函数。 内联成员函数(Inline Member Function)内联成员函数是指在类内部定义且声明为内联的成员函数。内联成员函数的函数体会在编译时被直接插入到调用点从而避免了函数调用的开销。内联成员函数通常用于实现短小、频繁调用的成员函数如访问器(getter)和修改器(setter)等。
对于短小、频繁调用的成员函数可以考虑将其定义为内联函数以提高执行效率。但需要注意过度使用内联函数可能会增加代码的体积和编译时间。将成员函数定义在类内部将成员函数的定义放在类的内部可以让编译器更容易进行内联优化。同时这样也可以提高代码的可读性和封装性。
下面是一个简单的例子展示了内联成员函数的使用:
class Rectangle {
private:int width;int height;public:Rectangle(int w, int h) : width(w), height(h) {}inline int getArea() const {return width * height;}inline void setWidth(int w) {width w;}inline void setHeight(int h) {height h;}
};在这个例子中getArea()setWidth()和setHeight()都是内联成员函数它们的函数体会在编译时被直接插入到调用点从而避免了函数调用的开销。
2.3 构造函数和析构函数
构造函数(Constructor)构造函数是一种特殊的成员函数用于初始化对象的数据成员。它与类同名没有返回类型可以有参数。构造函数在对象创建时自动调用用于确保对象在使用前处于一个有效的状态。 默认构造函数如果没有显式定义构造函数编译器会自动生成一个默认构造函数。默认构造函数没有参数会对对象进行默认初始化。可以通过将隐式默认构造函数定义为已删除来阻止编译器生成它。 // Default constructor
MyClass() delete;如果有任何类成员不是默认可构造则编译器生成的默认构造函数会定义为已删除。 例如类类型的所有成员及其类类型成员都必须具有可访问的默认构造函数和析构函数。 引用类型的所有数据成员和所有 const 成员都必须具有默认成员初始化表达式。 参数化构造函数带有参数的构造函数用于根据传入的参数初始化对象的数据成员。
构造函数的语法:
class MyClass {
public:MyClass(); // 默认构造函数MyClass(int value); // 参数化构造函数
};析构函数(Destructor)析构函数是一种特殊的成员函数用于在对象销毁时执行清理操作如释放动态分配的内存、关闭文件、断开网络连接等。析构函数的名称与类名相同前面加上~符号没有参数和返回值。析构函数在对象超出作用域、被显式删除或程序结束时自动调用。
默认析构函数如果没有显式定义析构函数编译器会自动生成一个默认析构函数默认析构函数没有任何操作。自定义析构函数用户根据需要定义的析构函数执行必要的清理操作。
下面是一个完整的例子展示了构造函数和析构函数的使用:
class MyClass {
public:MyClass() {cout Default constructor called. endl;}MyClass(int value) : data(value) {cout Parameterized constructor called. endl;}~MyClass() {cout Destructor called. endl;}private:int data;
};int main() {MyClass obj1; // 调用默认构造函数MyClass obj2(42); // 调用参数化构造函数return 0; // 对象超出作用域,调用析构函数
}输出结果:
Default constructor called.
Parameterized constructor called.
Destructor called.
Destructor called.2.4 列表初始化(c11)
C11引入了列表初始化(List Initialization)的概念提供了一种更加通用、一致的方式来初始化对象包括类的对象。列表初始化使用大括号{}来指定初始值可以用于各种类型的对象。
(1) 类成员的列表初始化使用列表初始化可以直接在类的定义中为数据成员指定初始值而不需要在构造函数中显式初始化。
class MyClass {
public:MyClass() {}private:int value{42};std::string name{John};std::vectorint numbers{1, 2, 3};
};(2) 构造函数的列表初始化在构造函数中可以使用列表初始化来初始化数据成员这提供了一种更加简洁、直观的方式。
class MyClass {
public:MyClass() : value{42}, name{John}, numbers{1, 2, 3} {}private:int value;std::string name;std::vectorint numbers;
};(3) 对象的列表初始化在创建类的对象时可以使用列表初始化来直接指定对象的初始值。
MyClass obj1{}; // 使用默认构造函数
MyClass obj2{42, John, {1, 2, 3}}; // 使用列表初始化(4) 返回对象的列表初始化在函数返回类的对象时可以使用列表初始化来直接创建和返回一个临时对象。
MyClass createObject() {return {42, John, {1, 2, 3}}; // 使用列表初始化返回临时对象
}(5) 聚合类的列表初始化对于聚合类(Aggregate Class)即没有用户提供的构造函数、基类和虚函数的类可以使用列表初始化来直接初始化其数据成员。
struct Point {int x;int y;
};Point p1{1, 2}; // 使用列表初始化2.5 const成员函数
const成员函数是一种特殊的类成员函数用于保证在该函数中不会修改对象的状态。在成员函数的声明和定义中在函数参数列表后面加上const关键字表示该函数是一个const成员函数。
class MyClass {
public:int getValue() const; // const成员函数声明
};int MyClass::getValue() const {return value; // const成员函数定义
}const成员函数不能修改对象的数据成员也不能调用其他非const成员函数(因为它们可能会修改对象状态)。这提供了一种契约保证了const成员函数的行为。
class MyClass {
public:int getValue() const {// value 42; // 错误:不能修改数据成员return value;}private:int value;
};可以同时提供一个成员函数的const和非const版本以适应不同的需求这称为const重载。
class MyClass {
public:int getValue() {return value; // 非const版本,可以修改数据成员}const int getValue() const {return value; // const版本,不能修改数据成员}private:int value;
};常量对象(即声明为const的对象)只能调用const成员函数不能调用非const成员函数这确保了常量对象的不可变性。
const MyClass obj;
obj.getValue(); // 调用const版本的getValue2.6 类作用域和静态成员
类作用域、作用域类枚举和静态常量成员是C中与类相关的重要概念它们定义了类成员的可见性、生命周期和访问方式。
(1) 类作用域(Class Scope)类作用域是指在类定义中声明的名称(如成员变量、成员函数、嵌套类型等)的可见范围。类作用域内的名称只能在类内部直接访问在类外部需要通过类名或对象名限定。
class MyClass {
public:void myFunction() {// 在类作用域内直接访问成员变量value 42;}private:int value;
};int main() {MyClass obj;// obj.value 42; // 错误:在类外部不能直接访问私有成员obj.myFunction(); // 通过对象名访问公共成员函数return 0;
}(2) 作用域类枚举(Scoped Enumerations)作用域类枚举是C11引入的一种强类型枚举它具有类作用域可以防止枚举值的命名冲突。作用域类枚举使用enum class关键字定义枚举值的名称仅在枚举类型的作用域内可见。
enum class Color { Red, Green, Blue };int main() {Color c Color::Red; // 使用作用域类枚举// int value Red; // 错误:枚举值名称在枚举类型作用域外不可见return 0;
}(3) 静态常量成员(Static Const Members)静态常量成员是类的一种特殊成员它具有静态存储期和常量特性。静态常量成员在类内部声明在类外部定义和初始化。它们可以在类的任何成员函数中访问也可以通过类名在类外部访问。
class MyClass {
public:static const int VALUE 42;
};const int MyClass::VALUE; // 在类外部定义和初始化静态常量成员int main() {int value MyClass::VALUE; // 通过类名访问静态常量成员return 0;
}静态数据成员不是给定的类类型的对象的一部分。 因此静态数据成员的声明不被视为一个定义。 在类范围中声明数据成员但在文件范围内执行定义。 这些静态类成员具有外部链接。
2.7 this指针
this指针是C中的一个特殊指针它是一个隐式参数存在于类的每一个非静态成员函数中。this指针指向当前对象的地址通过this指针可以访问当前对象的成员变量和成员函数。
this指针的类型是当前类的常量指针即const ClassName* const其中ClassName是当前类的名称。这意味着this指针指向的地址不能被修改也不能用于修改当前对象的常量成员。
在成员函数中可以使用this指针显式地访问当前对象的成员变量以消除名称冲突或提高代码的清晰度。
class MyClass {
public:void setValue(int value) {this-value value; // 使用this指针访问成员变量}private:int value;
};在某些成员函数中可以返回*this即当前对象的引用以支持链式调用或其他特殊用途。
class MyClass {
public:MyClass setValue(int value) {this-value value;return *this; // 返回当前对象的引用}private:int value;
};int main() {MyClass obj;obj.setValue(42).setValue(24); // 链式调用return 0;
}在const成员函数中this指针的类型是const ClassName* const这意味着不能通过this指针修改当前对象的成员变量。
class MyClass {
public:int getValue() const {return this-value; // 在const成员函数中使用this指针}private:int value;
};Once Day 也信美人终作土不堪幽梦太匆匆...... 如果这篇文章为您带来了帮助或启发不妨点个赞和关注再加上一个小小的收藏⭐ (◕‿◕)感谢您的阅读与支持~~~