网站建设找工作深圳网站制作网站建设

当前位置: 首页 > news >正文

网站建设找工作,深圳网站制作网站建设,设计导航网,西安seo引擎搜索优化C面向对象编程学习 前言一、C面向对象编程二、知识点学习1. 定义一个类1.1 使用struct定义1.2 使用class定义1.3 struct和class的区别 2. 类的定义方式2.1 单文件定义#xff08;Inline Definition#xff09;2.2 分离定义#xff08;Separate Definition#xff09;2.3 头… C面向对象编程学习 前言一、C面向对象编程二、知识点学习1. 定义一个类1.1 使用struct定义1.2 使用class定义1.3 struct和class的区别 2. 类的定义方式2.1 单文件定义Inline Definition2.2 分离定义Separate Definition2.3 头文件守卫 3. 访问修饰符4. 构造函数与析构函数4.1 构造函数Constructor4.2 析构函数Destructor 5. this指针6. 虚函数7. 继承8. 其余内容 总结 前言 注意本文只适合有C基础的朋友食用另本文章目的在于记录学习C面向编程学习的过程会引用到其他人的文章。 推荐文章【C核心】一文理解C面向对象超级详细作者数据知道 一、C面向对象编程 先由一段C面向对象编程的典例的代码引入学习 #include iostream #include string// 基类Animal class Animal { public: // 访问权限// 构造函数Animal(std::string name) : name(name) {}// 虚析构函数virtual ~Animal() {}// 虚函数用于发声virtual void makeSound() const 0; // 纯虚函数// 打印动物的名字void printName() const {std::cout My name is name std::endl;}protected:std::string name; // 动物的名字 };// 派生类子类Dog class Dog : public Animal { public:// 构造函数Dog(std::string name) : Animal(name) {}// 实现基类的纯虚函数void makeSound() const override {std::cout name says: Bark! std::endl;} };// 派生类Cat class Cat : public Animal { public:// 构造函数Cat(std::string name) : Animal(name) {}// 实现基类的纯虚函数void makeSound() const override {std::cout name_ says: Meow! std::endl;} };// 函数模板用于处理任何类型的Animal template typename AnimalType void makeAnimalSound(const AnimalType animal) {animal.makeSound(); }int main() {Dog dog(Rex);Cat cat(Whiskers);dog.printName();dog.makeSound();cat.printName();cat.makeSound();// 使用模板函数makeAnimalSound(dog);makeAnimalSound(cat);return 0; }二、知识点学习

  1. 定义一个类 在C中struct和class关键字都可以用来定义一个类但它们在默认的访问权限上有所不同。以下是使用struct和class定义同一个类的例子 1.1 使用struct定义 struct MyStruct {int publicData; // 默认为publicprivate:int privateData; // 私有成员public:MyStruct(int value) : privateData(value) {}int getPrivateData() const {return privateData;}void setPrivateData(int value) {privateData value;}private:void privateMethod() {// 私有方法} };1.2 使用class定义 class MyClass {int publicData; // 默认为privateprivate:int privateData; // 私有成员public:MyClass(int value) : privateData(value) {}int getPrivateData() const {return privateData;}void setPrivateData(int value) {privateData value;}private:void privateMethod() {// 私有方法} };1.3 struct和class的区别 在struct中如果没有指定访问修饰符成员默认是public的。在class中如果没有指定访问修饰符成员默认是private的。 从C11起你可以使用struct来定义一个简单的数据结构没有或很少的行为而class通常用于定义具有封装、继承和多态特性的对象强调一个类型是具有封装、继承和多态的对象。然而这只是一个编程习惯上的区分技术上你可以使用任何一个关键字来定义任何类型的类。
  2. 类的定义方式 在C中类的定义通常有两种主要方式一种是在单个文件中定义类的全部内容另一种是将类的声明通常称为头文件和定义通常称为源文件分开。 单文件定义通常用于小型项目或简单的类其中类的实现非常简短或者为了减少编译依赖。分离定义通常用于大型项目或复杂的类其中需要隐藏实现细节提高代码的可维护性和可读性。 2.1 单文件定义Inline Definition 在这种方式中类的定义被直接放在头文件中通常是在.h或.hpp扩展名的文件中。这种方式被称为内联定义或头文件中的定义。 示例 // MyClass.h #ifndef MYCLASS_H #define MYCLASS_Hclass MyClass { public:void function() {// 实现细节} private:int data; };#endif // MYCLASS_H在这种方式中每次包含头文件时类的定义都会被包含到使用它的每个源文件中。这可能会导致代码重复但可以减少编译依赖和提高编译速度。 2.2 分离定义Separate Definition 就是类的声明放在头文件.h或.hpp类的定义实现放在源文件.cpp。 头文件 MyClass.h
    // MyClass.h #ifndef MYCLASS_H #define MYCLASS_Hclass MyClass { public:void function(); private:int data; };#endif // MYCLASS_H源文件 MyClass.cpp
    // MyClass.cpp #include MyClass.hvoid MyClass::function() {// 实现细节data 42; // 访问私有成员 }在这种方式中类的实现被隐藏在源文件中只有声明被包含在其他文件中。这样做的好处是增加了模块化减少了重复代码并且使得单个类的定义更容易维护。 2.3 头文件守卫 这段代码是C预处理器指令用于防止头文件被多次包含这是一种常见的头文件保护技术。这种技术被称为“包含保护”或“头文件守卫”。下面是每个指令的解释 #ifndef MYCLASS_H - 这个指令检查一个宏在这个例子中是MYCLASS_H是否还未定义。#ifndef是“if not defined”的缩写。如果MYCLASS_H没有定义那么预处理器会继续处理下面的代码。 #define MYCLASS_H - 这个指令定义了MYCLASS_H宏。这样如果这个头文件被包含多次预处理器会记住MYCLASS_H已经被定义了并且跳过第二次及后续的包含。 #endif // MYCLASS_H - 这个指令标记了预处理条件块的结束。#endif指示预处理器停止处理条件块。注释// MYCLASS_H是为了提供额外的信息说明这个#endif与哪个#ifndef配对。这是一个编程习惯有助于在阅读代码时快速识别匹配的指令。
    包含保护的目的是防止头文件的内容被编译多次这可能发生在多个源文件都包含了同一个头文件的情况下。如果没有包含保护每次头文件被包含时它的代码都会被重新编译这不仅会导致编译错误如重复定义还可能降低编译效率。 例如如果你有以下头文件和源文件结构 // MyClass.h #ifndef MYCLASS_H #define MYCLASS_Hclass MyClass {// 类的定义 };#endif // MYCLASS_H// main.cpp #include MyClass.h #include MyClass.h // 第二次包含相同的头文件int main() {MyClass myObject;// 使用myObject }在没有包含保护的情况下MyClass的定义会被包含两次导致编译器报错因为它尝试定义同一个类两次。有了包含保护预处理器会识别出第二次包含是重复的并忽略它从而避免编译错误。 请注意#endif指令前的注释// MYCLASS_H是可选的但它有助于在阅读代码时快速定位匹配的#ifndef指令。
  3. 访问修饰符 1public——–公共的类外部可以访问 2protected—保护的类外部不可以访问 3private——-私有的类外部不能访问 解析 public公共的 类外部可以访问类的公共成员在定义类的外部是可见的可以直接通过类的实例来访问。示例class MyClass { public:int publicData; // 公共成员可以直接访问void publicMethod() {} // 公共成员函数可以直接调用 };MyClass obj; obj.publicData 10; // 直接访问公共成员变量 obj.publicMethod(); // 直接调用公共成员函数protected保护的 类外部不可以访问类的受保护成员在定义类的外部是不可见的不能直接通过类的实例来访问。但可以在派生类中访问如果一个类派生自具有受保护成员的基类那么这些受保护的成员在派生类中是可见的。示例class Base { protected:int protectedData; // 受保护成员不能直接访问 };class Derived : public Base { public:void accessBaseMembers() {protectedData 20; // 在派生类中可以访问基类的受保护成员} };Derived obj; // obj.protectedData 20; // 错误在类外部不能直接访问受保护成员 obj.accessBaseMembers(); // 正确通过派生类的公共接口访问基类的受保护成员private私有的 类外部不能访问类的私有成员在定义类的外部是不可见的不能直接通过类的实例来访问。类内部可以访问私有成员只能在定义它们的类内部被访问包括类的成员函数和友元类或友元函数。示例class MyClass { private:int privateData; // 私有成员不能直接访问void privateMethod() {} // 私有成员函数不能直接调用public:void publicMethod() {privateData 30; // 在类内部可以访问私有成员privateMethod(); // 在类内部可以调用私有成员函数} };MyClass obj; // obj.privateData 30; // 错误在类外部不能直接访问私有成员 // obj.privateMethod(); // 错误在类外部不能直接调用私有成员函数 obj.publicMethod(); // 正确通过公共成员函数间接访问私有成员4. 构造函数与析构函数 在C中构造函数和析构函数是特殊的成员函数它们分别用于初始化对象和清理对象使用资源。 构造函数主要作用在于创建对象时为对象的成员属性赋值构造函数由编译器自动调用无须手动调用。语法格式如下 构造函数语法类名(){} 析构函数主要作用在于对象销毁前系统自动调用执行一些清理工作。语法格式如下 析构函数语法 ~类名(){} 4.1 构造函数Constructor 构造函数是一种特殊的成员函数用于创建类的对象时初始化对象。它具有与类相同的名称且没有返回类型也不能被声明为const、volatile或static。构造函数可以有参数也可以没有参数无参数构造函数可以有多个构造函数构造函数重载以适应不同的初始化需求。 特点 没有返回值也不抛出异常除了析构函数外。可以有0个或多个参数。可以有默认参数。可以被重载以提供不同的初始化方式。 示例 class MyClass { public:// 无参数的构造函数MyClass() {// 初始化代码}// 带参数的构造函数MyClass(int value) {// 使用参数value进行初始化}// 带多个参数的构造函数MyClass(int value, const std::string name) {// 使用参数value和name进行初始化} };4.2 析构函数Destructor 析构函数是一种特殊的成员函数用于对象生命周期结束时执行清理工作。它用于释放对象在生命周期中分配的资源如动态分配的内存、文件句柄、网络连接等。析构函数的名称是在类名前加上波浪号~且析构函数不能有参数不能有返回值也不能被重载。 特点 没有返回值。不能带有参数。不能被重载。一个类只能有一个析构函数。 示例 class MyClass { public:// 构造函数MyClass() {// 分配资源如动态内存}// 析构函数~MyClass() {// 释放资源如动态内存} };在上述示例中当使用new创建MyClass对象时会调用构造函数进行初始化。当对象不再需要时比如超出作用域或者使用delete时会调用析构函数进行清理。
  4. this指针 在C中this 指针是一个特殊的指针它在每个非静态成员函数内部可用。this 指针指向调用成员函数的对象本身它允许成员函数访问对象的数据成员和成员函数。 作用 访问对象的成员成员函数经常需要访问调用它的那个对象的成员变量和其他成员函数。this 指针使得成员函数能够区分不同的对象即使它们拥有相同的成员名称。 链式调用this 指针可以用来返回对象本身从而实现链式调用。 区分成员变量和局部变量当成员函数中的局部变量与类的成员变量同名时this 指针可以用来区分它们。
    示例 class MyClass {int value;public:MyClass(int val) : value(val) {}int getValue() const {return value; // 使用this指针访问成员变量}MyClass set(int val) { // 成员函数返回对象的引用this-value val;return this; // 使用this指针返回对象本身}void printValue() const {int localValue 10; // 局部变量int memVarPtr this-value; // 使用this指针区分成员变量和局部变量int* localVarPtr localValue;// 输出指针地址以区分成员变量和局部变量std::cout Member variable value: *memVarPtr std::endl;std::cout Local variable value: *localVarPtr std::endl;} };int main() {MyClass obj(100);obj.printValue(); // 输出对象的成员变量和局部变量的值obj.set(200).set(300).set(400); // 链式调用std::cout Final value: obj.getValue() std::endl; // 输出最终值return 0; }注意事项 this 指针在静态成员函数中不可用因为静态成员函数不依赖于具体的对象实例。this 指针在普通成员函数中是隐式定义的不需要声明。this 指针通常不需要手动管理但了解其存在和作用对于编写更清晰和更有效的代码是有帮助的。在异常情况下如果成员函数被非法调用例如在一个未初始化的对象上this 指针可能不是一个有效的指针因此在处理异常和错误时需要小心。
  5. 虚函数 语法格式 virtual ReturnType FunctionName(Parameters) {// 函数实现 }这里的virtual关键字告诉编译器这个函数是虚函数可以被子类重写。 当通过基类指针或引用调用虚函数时如果对象实际是派生类的实例那么将调用派生类中的版本这就是多态。如果对象是基类实例则调用基类中的版本。 例如 class Base { public:virtual void show() {cout Base class show() endl;} };class Derived : public Base { public:void show() override { // C11中引入了override关键字来明确指出函数重写了基类中的虚函数cout Derived class show() endl;} };int main() {Base* b;Derived d;b d; // 基类指针指向派生类对象b-show(); // 输出Derived class show()展示了多态性return 0; }在这个例子中尽管b是基类Base的指针但由于它指向的是派生类Derived的对象所以调用的实际上是Derived类中的show方法。
  6. 继承 语法class A : public B; MyFrame::MyFrame() 表示MyFrame()是MyFrame的构造函数。 继承的主要优点包括 代码重用可以减少代码冗余提高开发效率。扩展性可以基于现有的类进行扩展增加新的功能。维护性修改基类会影响到所有派生类简化了维护工作。 在C中继承是通过在类定义时使用:和继承类型关键字如public, protected, private来实现的。例如 class Base { public:void show() {cout Base class show() endl;} };class Derived : public Base { // 使用public继承 public:void display() {cout Derived class display() endl;} };int main() {Derived d;d.show(); // 继承自Base类的show方法d.display(); // Derived类特有的display方法return 0; }在这个例子中Derived类通过public关键字继承了Base类。这意味着Derived类的对象可以访问Base类中所有公有的成员。 继承类型关键字决定了基类成员在派生类中的访问级别 public继承基类中的公有成员和保护成员在派生类中仍然是公有的和保护的。protected继承基类中的公有成员和保护成员在派生类中都变成保护的。private继承基类中的公有成员和保护成员在派生类中都变成私有的。
  7. 其余内容 推荐文章【C核心】一文理解C面向对象超级详细作者数据知道 总结 本来学的C没有学到面向对象编程这块应为主要用来刷算法题但由于最近一个项目学习需要到此方面知识故来学习一下。