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

01_类的概念和定义

01_类的概念和定义

上方视频是我在哔哩哔哩上的视频,讲解 怎么写一个简单的c++类 可以看看

一、类的基本概念

在 C++ 中,类是一种用户自定义的数据类型,它将数据(成员变量)和操作这些数据的函数(成员函数)封装在一起。类是面向对象编程(OOP)的核心概念之一,它提供了一种将数据和行为捆绑在一起的方式,并允许通过访问控制对数据进行保护。

类与对象的关系

类就像是一个蓝图或模板,它定义了一类对象的共同属性和行为。而对象则是类的实例,是根据类这个蓝图创建出来的具体实体。例如,我们可以定义一个 Person 类,然后根据这个类创建出像 “张三”、“李四” 这样的具体对象。

二、类的定义语法

在 C++ 中,类的定义以关键字 class 开头,后面跟着类的名称,然后是一对花括号 {},花括号内包含类的成员(成员变量和成员函数),最后以分号 ; 结束。

下面是一个简单的 Person 类的定义示例:

class Person {
private:// 私有成员变量std::string name;  // 姓名int age;           // 年龄public:// 公有成员函数// 默认构造函数Person() {name = "Unknown";age = 0;}// 带参数的构造函数Person(const std::string& n, int a) {name = n;age = a;}// 获取姓名std::string getName() const {return name;}// 获取年龄int getAge() const {return age;}// 设置年龄void setAge(int a) {if (a >= 0) {age = a;}}// 显示信息void displayInfo() const {std::cout << "Name: " << name << ", Age: " << age << std::endl;}
};

访问控制修饰符

在上面的示例中,我们看到了 privatepublic 这两个访问控制修饰符:

  • private:私有成员只能在类的内部访问,外部无法直接访问。私有成员通常用于隐藏类的实现细节,保护数据不被随意修改。
  • public:公有成员可以在类的外部访问,通常用于提供类的接口,让外部代码可以与类进行交互。
  • protected:保护成员与私有成员类似,但在继承关系中,子类可以访问父类的保护成员。

三、对象的创建和使用

定义了类之后,就可以创建该类的对象并使用对象的成员了。下面是一个使用 Person 类的示例:

#include <iostream>
#include <string>int main() {// 创建 Person 对象Person person1;  // 使用默认构造函数Person person2("Alice", 25);  // 使用带参数的构造函数// 访问公有成员函数std::cout << "Person 1: ";person1.displayInfo();  // 输出: Name: Unknown, Age: 0std::cout << "Person 2: ";person2.displayInfo();  // 输出: Name: Alice, Age: 25// 修改对象的属性person1.setAge(30);std::cout << "Person 1's new age: " << person1.getAge() << std::endl;  // 输出: 30return 0;
}

构造函数

构造函数是一种特殊的成员函数,它在创建对象时自动调用,用于初始化对象的状态。构造函数的名称必须与类名相同,并且没有返回类型。在上面的示例中,Person 类有两个构造函数:一个是默认构造函数,另一个是带参数的构造函数。

成员函数

成员函数是定义在类内部的函数,它们可以访问类的所有成员(包括私有成员)。成员函数可以在类的定义内部实现,也可以在类的外部实现。在类的外部实现成员函数时,需要使用作用域解析运算符 ::。例如:

// 在类的外部实现成员函数
void Person::displayInfo() const {std::cout << "Name: " << name << ", Age: " << age << std::endl;
}

四、类的封装

封装是面向对象编程的三大特性之一(另外两个是继承和多态)。封装的核心思想是将数据和操作数据的函数捆绑在一起,并通过访问控制来隐藏内部实现细节,只对外提供必要的接口。

在上面的 Person 类示例中,nameage 被声明为私有成员,外部代码无法直接访问它们。通过提供公有的 getName()getAge()setAge() 等接口函数,外部代码可以间接地访问和修改这些私有成员,这样可以确保数据的完整性和安全性。例如,setAge() 函数中对年龄进行了有效性检查,防止设置无效的年龄值。

五、类的继承

继承是面向对象编程的另一个重要特性,它允许我们创建一个新的类(派生类),继承另一个已有类(基类)的属性和行为。通过继承,可以实现代码的复用和层次化的组织。

下面是一个简单的继承示例:

// 基类
class Animal {
protected:std::string name;public:Animal(const std::string& n) : name(n) {}void eat() const {std::cout << name << " is eating." << std::endl;}virtual void makeSound() const {std::cout << name << " makes a sound." << std::endl;}
};// 派生类
class Dog : public Animal {
public:Dog(const std::string& n) : Animal(n) {}void makeSound() const override {std::cout << name << " barks." << std::endl;}void fetch() const {std::cout << name << " is fetching a ball." << std::endl;}
};// 派生类
class Cat : public Animal {
public:Cat(const std::string& n) : Animal(n) {}void makeSound() const override {std::cout << name << " meows." << std::endl;}
};

在上面的示例中,DogCat 类都继承自 Animal 类。它们继承了 Animal 类的 name 成员变量和 eat() 成员函数,并且各自重写了 makeSound() 函数以实现自己的行为。此外,Dog 类还添加了自己特有的 fetch() 函数。

六、类的多态

多态是面向对象编程的第三个重要特性,它允许我们通过基类的指针或引用来调用派生类的函数,从而实现运行时的动态绑定。多态的实现通常依赖于虚函数(virtual 关键字)。

下面是一个使用多态的示例:

int main() {Dog dog("Buddy");Cat cat("Whiskers");// 通过基类指针实现多态Animal* animal1 = &dog;Animal* animal2 = &cat;animal1->eat();      // 输出: Buddy is eating.animal1->makeSound(); // 输出: Buddy barks.animal2->eat();      // 输出: Whiskers is eating.animal2->makeSound(); // 输出: Whiskers meows.return 0;
}

在上面的示例中,Animal 类的 makeSound() 函数被声明为虚函数(virtual),这样在运行时会根据对象的实际类型来调用相应的函数。通过基类指针 animal1animal2 分别指向 DogCat 对象,调用 makeSound() 函数时会动态绑定到实际对象的函数实现,从而实现了多态。

七、总结

C++ 中的类是一种强大的用户自定义数据类型,它将数据和操作数据的函数封装在一起,实现了面向对象编程的核心概念。通过类,我们可以实现数据的封装、继承和多态,从而构建出更加模块化、可复用和可维护的代码。掌握类的定义和使用是学习 C++ 编程的重要一步。

http://www.dtcms.com/a/277220.html

相关文章:

  • websocket连接时发生未知错误
  • sqli-labs靶场通关笔记:第9关 时间盲注
  • 快速生成 Android 的 Splash 的 9 Patch 图片
  • 【零基础入门unity游戏开发——unity3D篇】3D光源之——unity反射和反射探针技术
  • AI进化论12:大语言模型的爆发——GPT系列“出圈”,AI飞入寻常百姓家
  • Kafka——Kafka 线上集群部署方案怎么做?
  • c语言初阶 结构体
  • 【Python】venv:配置独立镜像源
  • 常用的docker命令备份
  • 007_用例与应用场景
  • python 列表(List) vs. 元组(Tuple):什么时候该用不可变的元组?它们在性能和用途上有什么区别?
  • 暑期自学嵌入式——Day01(C语言阶段)
  • 协程的基本使用
  • 【保姆级图文详解】MCP架构(客户端-服务端)、三种方式使用MCP服务、Spring AI MCP客户端和服务端开发、MCP部署方案、MCP安全性
  • 基于 CentOS 7 的 LVS+DR+Web+NFS 旅游攻略分享平台部署
  • CentOS系统下前后端项目部署攻略
  • 从 Manifest V2 升级到 Manifest V3:常见问题与解决方案
  • vue-component
  • [Linux入门 ] RAID存储技术概述
  • (S4)Efficiently Modeling Long Sequences with Structured State Spaces论文精读(逐段解析)
  • [Rust 基础课程]Hello World
  • 数据结构 单链表(2)--单链表的实现
  • 聊一聊Java生态接口测试常见的框架
  • 在 Spring Boot 中使用 MyBatis 的 XML 文件编写 SQL 语句详解
  • MySQL SQL语句精要:DDL、DML与DCL的深度探究
  • Design Compiler:什么是代价函数(Cost Function)
  • HarmonyOS组件/模板集成创新活动-元服务小云体重管理引入案例(步骤条UI组件)
  • python赤道上空的大气环流剖面图(纬向-高度剖面)
  • 多级@JsonTypeInfo和@JsonSubTypes注解使用详解及场景分析
  • 剑指offer59_翻转单词顺序