c++的笔记

文章目录

    • 友元
      • 关键点说明:
      • 运行输出:
      • 友元类的例子
    • 使用友元的情况
      • 1. **需要外部函数直接操作类的私有成员**
        • 示例场景:打印类的数据
      • 2. **两个类之间需要紧密协作**
        • 示例场景:管理类和数据类
      • 3. **操作符重载需要访问私有成员**
        • 示例场景:重载输出操作符
      • 4. **测试或调试需要访问内部状态**
        • 示例场景:调试工具
      • 注意事项和使用建议
      • 总结
    • 继承
      • 输出:
      • 关键点解释
        • 1. **基类(Animal)**
        • 2. **派生类(Dog)**
        • 3. **继承类型**
        • 4. **方法重写**
    • using type = int;
      • 类型别名基本用法
        • 输出:
        • 特点:
      • 与虚函数结合的示例
        • 输出:
      • 代码中的关键点
      • `using` vs `typedef`
        • 优势:
      • 使用场景

下面是一个简单的C++面向对象编程示例,展示类、对象和基本成员的使用:

#include <iostream>
#include <string>
#include <windows.h> using namespace std;// 定义一个简单的类
class Person {
private:string name;    // 私有成员变量int age;public:// 构造函数Person(string n, int a) {name = n;age = a;}// 成员函数void introduce() {cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;}
};int main() {SetConsoleOutputCP(CP_UTF8);  // 设置控制台为 UTF-8 编码// 创建对象Person person1("Alice", 25);// 调用成员函数person1.introduce();return 0;
}

这个程序展示了C++面向对象的基本特性:

  1. 类定义 (class Person):包含私有数据成员和公有成员函数
  2. 封装:name 和 age 是私有的,只能通过类的成员函数访问
  3. 构造函数:用于初始化对象
  4. 对象创建:使用类创建具体实例
  5. 成员函数:定义对象的行为

运行输出:

Hello, my name is Alice and I am 25 years old.

友元

下面是一个展示C++中友元(friend)功能的简单示例。友元允许特定的函数或类访问另一个类的私有成员:

#include <iostream>
#include <string>using namespace std;class Person {
private:string name;int age;public:// 构造函数Person(string n, int a) {name = n;age = a;}// 声明友元函数friend void showInfo(Person p);
};// 友元函数定义,可以访问Person的私有成员
void showInfo(Person p) {cout << "Name: " << p.name << ", Age: " << p.age << endl;
}int main() {// 创建对象Person person1("Bob", 30);// 调用友元函数showInfo(person1);return 0;
}

关键点说明:

  1. 友元声明:在 Person 类中通过 friend void showInfo(Person p); 声明 showInfo 为友元函数。
  2. 访问权限:尽管 nameage 是私有的,showInfo 函数仍能直接访问它们,因为它是友元。
  3. 使用场景:友元通常用于需要打破封装但又必须访问私有成员的情况。

运行输出:

Name: Bob, Age: 30

友元类的例子

如果你想要看友元类的用法,这里是一个扩展示例:

#include <iostream>
#include <string>using namespace std;class Person {
private:string name;int age;public:Person(string n, int a) : name(n), age(a) {}// 声明另一个类为友元friend class InfoPrinter;
};// 友元类
class InfoPrinter {
public:void display(Person p) {cout << "Name: " << p.name << ", Age: " << p.age << endl;}
};int main() {Person person1("Alice", 25);InfoPrinter printer;printer.display(person1);return 0;
}

在这个例子中,InfoPrinter 类是 Person 的友元类,因此它可以访问 Person 的私有成员。输出与之前相同,但展示了类级别的友元关系。

使用友元的情况


1. 需要外部函数直接操作类的私有成员

当一个独立的函数需要访问类的私有数据,且不适合作为类的成员函数时,可以使用友元函数。

示例场景:打印类的数据
#include <iostream>
#include <string>using namespace std;class Box {
private:double width;double height;public:Box(double w, double h) : width(w), height(h) {}// 声明友元函数friend void printArea(Box b);
};// 友元函数直接访问私有成员
void printArea(Box b) {double area = b.width * b.height;cout << "Area: " << area << endl;
}int main() {Box box(5.0, 3.0);printArea(box);return 0;
}

使用情况printArea 不属于 Box 类,但需要计算和访问其私有成员。将其声明为友元避免了添加额外的公有 getter 函数。


2. 两个类之间需要紧密协作

当两个类相互依赖,并且一个类需要访问另一个类的私有成员时,可以将其中一个类声明为另一个类的友元。

示例场景:管理类和数据类
#include <iostream>
#include <string>using namespace std;class Employee {
private:string name;double salary;public:Employee(string n, double s) : name(n), salary(s) {}// 声明 Manager 为友元类friend class Manager;
};class Manager {
public:void adjustSalary(Employee& e, double newSalary) {e.salary = newSalary;  // 直接访问私有成员cout << e.name << "'s new salary: " << e.salary << endl;}
};int main() {Employee emp("John", 50000);Manager mgr;mgr.adjustSalary(emp, 60000);return 0;
}

使用情况Manager 需要直接修改 Employee 的私有成员 salary,通过友元关系实现紧密协作。


3. 操作符重载需要访问私有成员

在重载操作符(如 +, <<)时,如果操作符函数不是类的成员函数,通常需要访问类的私有数据,这时可以声明为友元。

示例场景:重载输出操作符
#include <iostream>
#include <string>using namespace std;class Point {
private:int x;int y;public:Point(int xVal, int yVal) : x(xVal), y(yVal) {}// 声明友元函数重载 <<friend ostream& operator<<(ostream& os, const Point& p);
};// 友元函数实现
ostream& operator<<(ostream& os, const Point& p) {os << "(" << p.x << ", " << p.y << ")";return os;
}int main() {Point p(3, 4);cout << p << endl;return 0;
}

使用情况<< 操作符需要访问 Point 的私有成员 xy,通过友元实现简洁的输出。


4. 测试或调试需要访问内部状态

在开发过程中,为了测试类的私有成员状态,可以临时使用友元函数或友元类。

示例场景:调试工具
#include <iostream>using namespace std;class System {
private:int status;public:System(int s) : status(s) {}// 声明友元函数用于调试friend void debugStatus(System sys);
};void debugStatus(System sys) {cout << "System status: " << sys.status << endl;
}int main() {System sys(42);debugStatus(sys);return 0;
}

使用情况debugStatus 用于检查 System 的内部状态,便于调试。


注意事项和使用建议

  • 谨慎使用:友元打破了封装性,可能导致代码维护困难。通常优先考虑使用公有接口(getter/setter)或成员函数。
  • 替代方案:如果只是简单的数据访问,可以用公有方法代替;如果涉及复杂逻辑,可以考虑继承或组合。
  • 典型应用:友元在操作符重载、紧密相关的类(如容器和迭代器)以及特殊工具函数中较为常见。

总结

友元的使用情况主要集中在:

  1. 外部函数需要访问私有数据(如打印、计算)
  2. 类间紧密协作(如管理类和数据类)
  3. 操作符重载(如 <<, +
  4. 测试和调试需求

继承

下面是一个展示C++继承(Inheritance)基本概念的简单示例,包括基类、派生类和访问控制:

父类继承下来,会继承三样东西:
1.成员变量
2.成员函数
3.类型定义

#include <iostream>
#include <string>using namespace std;// 基类
class Animal {
protected:  // protected成员可被派生类访问string name;int age;public:Animal(string n, int a) : name(n), age(a) {}void eat() {cout << name << " is eating." << endl;}
};// 派生类(公有继承)
class Dog : public Animal {
private:string breed;public:// 构造函数,调用基类构造函数Dog(string n, int a, string b) : Animal(n, a), breed(b) {}void bark() {cout << name << " (a " << breed << ") is barking!" << endl;}// 重写基类方法void eat() {cout << name << " (a " << breed << ") is eating dog food." << endl;}
};int main() {// 创建基类对象Animal animal("Generic", 5);animal.eat();// 创建派生类对象Dog dog("Max", 3, "Golden Retriever");dog.eat();   // 调用重写后的方法dog.bark();  // 调用派生类特有方法return 0;
}

输出:

Generic is eating.
Max (a Golden Retriever) is eating dog food.
Max (a Golden Retriever) is barking!

关键点解释

1. 基类(Animal)
  • 定义了通用的属性(name, age)和行为(eat())。
  • 使用 protected 访问修饰符,使派生类可以访问这些成员。
2. 派生类(Dog)
  • 使用 public 继承方式从 Animal 继承。
  • 继承了基类的 nameage,并添加了自己的属性 breed
  • 通过构造函数初始化列表调用基类构造函数:Animal(n, a)
3. 继承类型
  • 公有继承(public):基类的公有成员在派生类中仍为公有,受保护成员仍为受保护。
  • 私有继承(private):基类的公有和受保护成员在派生类中变为私有。
  • 受保护继承(protected):基类的公有成员变为受保护,受保护成员保持不变。
4. 方法重写
  • Dog 类重写了基类的 eat() 方法,提供了更具体的实现。
  • 基类的原始 eat() 方法被覆盖,但仍可通过作用域解析运算符(如 Animal::eat())调用。

using type = int;

你提到的 using type = int; 是C++11引入的类型别名(Type Alias)语法,用于为现有类型定义一个新的名称。它类似于 typedef,但更灵活且可读性更好。下面我将解释它的用法,并结合虚函数和多态的上下文提供一个相关示例。


类型别名基本用法

#include <iostream>using namespace std;// 类型别名
using type = int;  // "type" 现在是 "int" 的别名int main() {type number = 42;  // 等价于 int number = 42;cout << "Number: " << number << endl;return 0;
}
输出:
Number: 42
特点:
  • using type = int; 定义 typeint 的别名。
  • typedef int type; 等价,但 using 语法更直观,且支持模板。

与虚函数结合的示例

假设我们在一个多态场景中使用类型别名来简化代码:

#include <iostream>
#include <string>
#include <vector>using namespace std;// 类型别名
using Distance = double;  // 为 double 定义别名// 基类
class Vehicle {
protected:string name;public:Vehicle(string n) : name(n) {}// 虚函数virtual Distance calculateFuelEfficiency() const {return 0.0;  // 默认实现}virtual ~Vehicle() {}
};// 派生类1
class Car : public Vehicle {
private:Distance miles;Distance gallons;public:Car(string n, Distance m, Distance g) : Vehicle(n), miles(m), gallons(g) {}Distance calculateFuelEfficiency() const override {return miles / gallons;  // 计算每加仑英里数}
};// 派生类2
class Bike : public Vehicle {
private:Distance miles;Distance liters;public:Bike(string n, Distance m, Distance l) : Vehicle(n), miles(m), liters(l) {}Distance calculateFuelEfficiency() const override {return miles / liters;  // 计算每升英里数}
};int main() {vector<Vehicle*> vehicles;vehicles.push_back(new Car("Toyota", 300.0, 10.0));vehicles.push_back(new Bike("Harley", 120.0, 2.0));for (const auto* v : vehicles) {Distance efficiency = v->calculateFuelEfficiency();cout << "Fuel efficiency: " << efficiency << " miles per unit" << endl;}for (auto* v : vehicles) {delete v;}return 0;
}
输出:
Fuel efficiency: 30 miles per unit
Fuel efficiency: 60 miles per unit

代码中的关键点

  1. 类型别名(using Distance = double;

    • double 定义为 Distance,提高了代码的可读性,表示这是一个距离或效率相关的类型。
    • 在类中统一使用 Distance,如果将来需要更改类型(如改为 float),只需改别名定义。
  2. 虚函数(calculateFuelEfficiency

    • 基类提供默认实现,返回类型为 Distance
    • 派生类 CarBike 重写该函数,计算不同的燃料效率。
  3. 运行时多态

    • 通过 Vehicle* 指针调用 calculateFuelEfficiency(),运行时根据对象类型执行对应的实现。

using vs typedef

  • typedef(C++98):
    typedef double Distance;  // 传统方式
    
  • using(C++11):
    using Distance = double;  // 现代方式
    
优势:
  • using 支持模板别名,而 typedef 不支持:
    template<typename T>
    using Ptr = T*;  // 模板别名
    Ptr<int> p = nullptr;  // int* p
    
  • using 语法更直观,类似于赋值。

使用场景

  1. 提高可读性
    • Distance 表示距离相关的变量,而不是直接用 double
  2. 类型统一
    • 在大型项目中,统一类型别名便于维护。
  3. 模板编程
    • using 在模板中更灵活,如定义容器别名:
      template<typename T>
      using Vec = std::vector<T>;
      Vec<int> v;  // 等价于 std::vector<int>
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/42816.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3DGS较真系列

目录 引言 三维高斯飞溅(3DGS) 总体流程 SFM算法 1.特征提取&#xff1a; 2.特征匹配&#xff1a; 3.图像对优选&#xff1a; 4.相机位姿估计及空间点坐标获取&#xff1a; 5.三角化确立新图像地图点&#xff1a; 6.重建场景及其约束&#xff1a; 3DGS 1.捏雪球 2…

【计网】网络、互连网、互联网的认识和区分

一、些杂乱的知识点&#xff1a; 1.Internet是由数量极大的各种计算机网络连接起来的。 2.世界上最大的计算机网络Internet叫互联网&#xff08;互联网 &#xff01; 互连网&#xff09;。 3.互联网的两个基本特点&#xff1a; &#xff08;1&#xff09;互通性&#xff1a…

手机零售行业的 AI 破局与创新降本实践 | OceanBase DB大咖说

OceanBase《DB 大咖说》第 20 期&#xff0c;我们邀请了九机与九讯云的技术总负责人&#xff0c;李远军&#xff0c;为我们分享手机零售企业如何借力分布式数据库OceanBase&#xff0c;赋能 AI 场景&#xff0c;并通过简化架构实现成本管控上的突破与创新。 李远军于2016年加入…

高并发金融系统,“可观测-可追溯-可回滚“的闭环审计体系

一句话总结 在高并发金融系统中&#xff0c;审计方案设计需平衡"观测粒度"与"系统损耗"&#xff0c;通过双AOP实现非侵入式采集&#xff0c;三表机制保障操作原子性&#xff0c;最终形成"可观测-可追溯-可回滚"的闭环体系。 业务痛点与需求 在…

迅为iTOP-RK3576人工智能开发板Android 系统接口功能测试

2.1 开机启动 开发板接通电源&#xff0c;并按下电源开关&#xff0c;系统即启动&#xff0c;在启动过程中&#xff0c;系统会显示下图中的开机画面&#xff0c;它们分别是 Android 系统启动时的 Logo 画面&#xff1a; 最后会显示如下解锁画面&#xff1a; 2.2 命令终端 将…

Linux云计算SRE-第二十一周

构建单节点prometheus&#xff0c;部署node exporter和mongo exporter。构建kibana大盘。包含主机PU使用率&#xff0c;主机MEM使用率&#xff0c;主机网络包速度。mongo db大盘&#xff0c;包含节点在线状态&#xff0c;读操作延迟等 一、实验环境准备 - 节点信息&#xff1…

蓝桥杯 - 简单 - 产品360度展示

介绍 在电子商务网站中&#xff0c;用户可以通过鼠标或手势交互实现 360 度全方位查看产品&#xff0c;提升用户体验。现在需要你设计一个 Pipeline 管道函数&#xff0c;用于控制 360 度展示产品的动画序列&#xff0c;通过管道连接各个动画步骤&#xff0c;使产品以流畅的方…

【Rust基础】使用LanceDB构建高性能以图搜图服务

简介 最近使用LanceDB构建了一个以图搜图服务&#xff0c;用于相似图片检索&#xff0c;支持以下功能&#xff1a; 搜索 支持向量搜索&#xff0c;查找相似图片支持通过item_id搜索精确搜索 数据管理 支持添加数据、批量导入CSV或JSON数据支持已有数据修改、删除 API 提供HTT…

蓝桥杯备考:模拟算法之排队接水

简单的模拟就行了&#xff0c;把他们的时间排序&#xff0c;时间最少的先上&#xff0c;然后算出每个人的等待时间的平均值 #include <iostream> #include <algorithm> using namespace std; const int N 1e310; int n; double sum; double ret; struct node{int…

zynq7000 + ucos3 + lwip202_v1_2调试过程

1 现在裸机应用上验证lwip 跑起来可能会报错&#xff0c;看下面的链接解决 zynq 网卡Phy setup error问题 zynq 网卡Phy setup error问题-CSDN博客 2 ping同以后&#xff0c;在zynq上添加ucos系统 链接如下&#xff1a; ZYNQ移植uCOSIII_zynq ucos-CSDN博客 3 移植lwip协议…

如何用 Postman 正确传递 Date 类型参数,避免服务器解析错误?

如何在 Postman 中传递 Date 类型参数。调试工具如何模拟发送用户端的当前时间呢&#xff1f; Postman 传递 Date 类型参数教程

卷积神经网络在图像分割中的应用:原理、方法与进展介绍

摘要 图像分割是计算机视觉领域的核心任务之一&#xff0c;旨在将图像划分为具有语义意义的区域。卷积神经网络&#xff08;CNN&#xff09;因其强大的特征提取能力&#xff0c;已成为图像分割的主流方法。本文系统介绍了CNN在图像分割中的关键技术&#xff0c;包括全卷积网络…

VMware Windows Tools 存在认证绕过漏洞(CVE-2025-22230)

漏洞概述 博通公司&#xff08;Broadcom&#xff09;近日修复了 VMware Windows Tools 中存在的一个高危认证绕过漏洞&#xff0c;该漏洞编号为 CVE-2025-22230&#xff08;CVSS 评分为 9.8&#xff09;。VMware Windows Tools 是一套实用程序套件&#xff0c;可提升运行在 VM…

DeepSeek-V3-0324对比OpenAI GPT-4o和Gemini 2.5 Pro

以下是DeepSeek-V3-0324、OpenAI GPT-4o与谷歌Gemini 2.5 Pro模型的更新点及优化对比总结&#xff1a; 1. DeepSeek-V3-0324 开源地址&#xff1a;https://huggingface.co/deepseek-ai/DeepSeek-V3-0324 核心更新与优化 性能提升&#xff1a; 采用6850亿参数MoE架构&#xff…

视频编码器的抉择:x264、x265、libaom、vvenc 对比测试实验

264、x265、libaom、vvenc 对比测试实验 测试机器配置&#xff1a;Apple M1 Pro -16G编码器版本&#xff08;选择自己编译&#xff09;&#xff1a;所有源码都是当前最新更新的状态&#xff0c;此外各类编码具体的编译过程可参考我的相关系列博客。 编码器GitHubx264git clon…

【极速版 -- 大模型入门到进阶】LORA:大模型轻量级微调

文章目录 &#x1f30a; 有没有低成本的方法微调大模型&#xff1f;&#x1f30a; LoRA 的核心思想&#x1f30a; LoRA 的初始化和 r r r 的值设定&#x1f30a; LoRA 实战&#xff1a;LoraConfig参数详解 论文指路&#xff1a;LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE M…

初识MySQl · 内置函数

目录 前言&#xff1a; 日期类函数 字符串函数 数学类函数 其他函数 前言&#xff1a; 在前文的学习我们已经简单了解了部分函数&#xff0c;比如count()函数什么的&#xff0c;今天我们主要是笼统的学习一下MySQL中的函数&#xff0c;仅仅从使用的角度来学习&#xff0c…

Python每日一题(7)

Python每日一题 2025.3.27 一、题目二、分析三、自己源代码四、deepseek答案五、源代码与ai分析 一、题目 question["""编写程序,生成包含20个随机数的列表,然后将前十个元素升序排列,后10个元素降序排列,并输出结果""" ]二、分析 今天本来写了…

一些需要学习的C++库:CGAL和Eysshot

写在前面&#xff1a; 从开始工作到现在&#xff0c;去过多家公司&#xff0c;多个行业&#xff0c; 虽然大部分时间在通信业&#xff0c;但也有其它的行业的工作没有做完&#xff0c;但也很感兴趣。每次想要研究一下时&#xff0c;总是想不起来。 这里写一些信息&#xff0c;…

嵌入式linux系统中对应的文件锁详细实现方法

//文件锁:flock用于对文件加锁或者解锁但是只能产生建议性锁,并且同一个文件不会同时 具有共享锁和互斥锁。 第一:flock函数对应的要素 头文件: #include <sys/file.h> 函数原型:int flock(int fd,int operation) 参数: fd:表示需要加锁文件的文件描述符 operati…