C++入门(有C语言基础)

string类

  1. string类初始化的方式大概有以下几种:
    string str1;string str2 = "hello str2";string str3("hello str3");string str4(5, 'B');string str5[3] = {"Xiaomi", "BYD", "XPeng"};string str6 = str5[2];str1 = "nihao str1";
  1. 通过size()length() 函数可以获取字符串的长度:
	// 获取长度,不会包含'\0'cout << str1.size() << endl;cout << str1.length() << endl;cout << str4.size() << endl;cout << str5[0].size() << endl;
  1. 两种访问字符的方式:通过 [] 运算符或 at() 方法来访问字符串中的某个字符。at() 具有边界检查,如果访问越界会抛出异常,而 [] 不会做边界检查[]导致的越界会产生未定义行为,越界后会访问到其他地址,系统不会报错;at()只要一越界就要抛出错误,程序终止。一个string占32个字节。
    cout << str2[7] << endl;cout << str2.at(7) << endl;cout << str5[0][2] << endl;cout << str5[0].at(2) << endl;
  1. 拼接字符串:
#include <stdio.h>
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{string str1 = "成长是永远";string str2 = "离别是空悬";cout << str1 + str2 << endl;return 0;
}
  1. 比较字符串:可以直接使用 ==, !=, <, >, <=, >= 来比较两个字符串的字典顺序。对应ASCII码值大的就大,逻辑表达式为真返回1,为假返回0.
	string str1 = "abc";string str2 = "xyz";cout << (str1 <= str2) << endl;
  1. 子字符串提取:substr() 函数用于提取子字符串。它接受两个参数:起始索引和长度(可选)
    string str1 = "abcdefghijkl";string str2 = str1.substr(1, 10);cout << str2 << endl;
  1. 插入删除和替换操作:
string str1 = "hello"; 
str1.insert(5, " world");// 表示在第5个字符后插入字符串string str1 = "hello world";
str1.erase(5, 3);  // 删除第5个字符之后的3个字符string str1 = "hello world";
str1.replace(5, 6, "C++"); // 从第5个字符后开始替换,替换6个字符,替换为“C++”
  1. 查找字符串:find() 函数可以查找子字符串或字符的第一个出现位置,如果没有找到,find() 会返回 std::string::npos,这里因为我开头用了using namespace std;,所以不需要再用std::声明
	string str1 = "hello world";if (str1.find("world") != string::npos){cout << "I find it" << endl;}else{cout << "I can't find it" << endl;}
  1. C++风格字符串与C风格字符串转换:
	// `std::string` 转换为C风格字符串(`const char*`)string str1 = "hello world";const char *str2 = str1.c_str();cout << str2 << endl;// C风格字符串转换为 `std::string`const char *str1 = "hello world";string str2(str1);cout << str2 << endl;
  1. 内存管理:string会自动处理内存分配和释放,不需要手动管理内存。string通过深拷贝的方式处理赋值操作,确保每个字符串对象都有自己独立的内存。
  2. 什么是深拷贝?什么是浅拷贝?
    • 深拷贝:深拷贝是在拷贝的时候将内容申请内存,重新拷贝一份,放到内存中,指针指向这个新拷贝的部分,这样就不会出现析构的时候重复释放的问题了。
    • 浅拷贝:浅拷贝就是增加了一个指向相同堆区的指针,这将导致在析构的时候会重复释放。默认的拷贝构造和运算符重载都是浅拷贝。
  3. 什么是析构:析构(Destructor)是一个特殊的成员函数,用于在对象生命周期结束时清理资源并执行必要的清理工作。析构函数的主要目的包括释放对象在其生命周期内分配的动态内存、关闭文件句柄、释放网络连接等。简单理解就是清理资源的成员函数。

函数

  1. 函数可以设置默认参数,如果调用时不传入参数则使用默认参数值:
void nameCountry(string name = "China")
{cout << name << endl;
}
  1. 指针传递和引用传递:
    1. 指针传递在C语言和C++中都能使用,指针传递是通过传递变量的地址来间接修改变量的值。
    2. 引用传递,只能在C++中使用。如下第一种函数就是引用传递。即直接操作传入的变量的引用,传递给函数时,函数内部对引用变量的修改会直接反映到原始变量上。
void swap(int &a, int &b)
{int temp = a;a = b;b = temp;
}void swap(int *a, int *b)
{int temp = *a;*a = *b;*b = temp;
}
  1. 函数的重载:是一种允许在同一个作用域内定义多个具有相同名字但参数列表不同的函数的特性。
    1. 重载规则:
      1. 参数的类型不同
      2. 参数的个数不同
      3. 参数的顺序不同
    2. 不允许重载的情况:
      1. 仅有返回值不同(函数的返回类型不能作为函数重载的依据)
      2. 函数使用默认参数时,可能会导致重载冲突(默认参数的存在导致二义性)
    3. const 修饰符可以参与函数重载。
    4. 数组和指针的重载:数组类型会退化为指针。(在 C语言 中,数组作为函数参数时也会 退化为指针。)
// 原始参照  
int funcPlus(int x, double y)  
{  cout << "这是funcPlus1" << endl;  return x + (int)y;  
}  // 参数类型不同  
int funcPlus(double x, double y)  
{  cout << "这是funcPlus2" << endl;  return (int)(x + y);  
}  // 参数个数不同  
int funcPlus(int x)  
{  cout << "这是funcPlus3" << endl;  return x * x;  
}  // 参数顺序不同  
int funcPlus(double x, int y)  
{  cout << "这是funcPlus4" << endl;  return (int)(x + y);  
}// 以下这种重载也是不允许的
int func(int x, int y = 10)  
{  cout << "这是funcPlus5" << endl;  return x + (int)y;  
}  int func(int x)  
{  cout << "这是funcPlus6" << endl;  return x;  
}void func(int &x); // 非 const 引用 
void func(const int &x); // const 引用,允许重载// 下面这两种不允许重载,因为数组arr[]会退化为指针
void func(int arr[])  
{  cout << "arr[]" << endl;  cout << arr[0] << endl;  
}  void func(int *arr)  
{  cout << "*arr" << endl;  cout << arr[0] << endl;  
}

类与多态性

  1. OOP:面向对象编程
  2. 类在声明时是不申请内存的,只有在实例化时才会初始化(分配)内存
  3. C++支持类的多继承;Java不支持类的多继承(但支持接口的多继承)
class Person
{
private:int age;public:string name;Person(int a, string name);~Person();  // 析构函数
};// 类内声明,类外定义
Person::Person(int age, string name)
{cout << "构造函数执行:" << endl;this->age = age;this->name = name;
}Person::~Person()
{cout << "析构函数执行:" << endl;
}
  1. 析构函数的作用:主要作用是在对象的生命周期结束时执行清理工作
    1. 释放动态分配的内存:运行过程中通过 newmalloc 等函数动态分配了内存,析构函数负责调用 deletefree 来释放这些内存。
    2. 释放其他系统资源:对象可能持有除内存以外的系统资源,比如文件句柄、网络连接、数据库连接等。
    3. 执行其他清理工作:析构函数可以用于任何需要在对象销毁时执行的操作,比如保存数据、记录日志等。
    4. 析构函数不接受参数,不能重载
    5. 如果创建了多个实例,析构函数就会执行多次。
  2. 类的访问控制:
    1. public:公开的成员可以在类外部访问。
    2. private:私有的成员只能在类内部访问,不能直接在类外部使用,但可以通过类方法间接调用。
    3. protected:受保护的成员可以在类内部和派生类(如子类)中访问。
  3. 类的静态成员:
    1. 静态成员变量:属于类本身,而不是某个对象。它在所有对象中共享
    2. 静态成员函数:只能访问静态成员变量,不依赖于对象。静态成员可以通过类名直接调用,如:Person::getCount()其中Person是类名,getCount()是静态成员函数
  4. 继承:
    1. 继承 允许一个类(派生类)从另一个类(基类)继承属性和行为。
    2. C++支持单继承和多继承。
    3. 派生类可以直接使用基类的公有和受保护成员。
class Animals
{
public:void eat(){cout << "eating" << endl;}
};class Dog : public Animals
{
public:void bark(){cout << "wow wow" << endl;}
};
  1. 友元函数:友元函数不是类的成员函数,但可以访问类的私有和受保护成员。它是在类外定义的,但具有特殊权限。
class Person
{
private:int age;public:Person(int age){this->age = age;}friend void getAge(Person);
};void getAge(Person per)
{cout << "岁数是:" <<per.age << endl;
}
  1. 多态:
    1. 多态性允许同一个函数或方法在不同的对象上表现出不同的行为。
    2. C++ 中的多态性通过虚函数、继承和指针或引用实现。
    3. 基本概念:
      1. 编译时多态(静态多态):通过函数重载和运算符重载实现,编译时决定。
      2. 运行时多态(动态多态):通过继承和虚函数实现,运行时决定。
  2. 虚函数:
    1. sound() 是基类 Animal 中的虚函数,DogCat 类分别重写了这个函数。
    2. 在运行时,animalPtr 指向不同的派生类对象时,会根据实际对象的类型来调用相应的 sound() 方法,这就是 运行时多态
  3. 纯虚函数与抽象类:
    1. 纯虚函数 是在基类中声明但没有实现的虚函数。
    2. 通过定义纯虚函数,基类变为 抽象类,它不能被实例化,只能作为派生类的基类使用。
  4. 纯虚函数与抽象类的代码如下:
#include <iostream>
using namespace std;class Animal
{
public:virtual void sound() = 0;
};class Dog : public Animal
{
public:// override 关键字不是必须的,但它是一个强烈推荐使用的修饰符。void sound() override{cout << "Dog barks" << endl;}
};class Cat : public Animal
{
public:void sound() override{cout << "Cat meow" << endl;}
};int main(int argc, char const *argv[])
{Animal *animalptr;Dog dog;Cat cat;// 基类指针指向派生类对象animalptr = &dog;animalptr->sound();  // 输出Dog barksanimalptr = &cat;animalptr->sound();  // 输出Cat meowreturn 0;
}
  1. 多态与析构函数:
    1. 通过基类指针删除派生类对象时,如果基类的析构函数不是 virtual,则可能会发生 内存泄漏
    2. 因为如果基类指针的析构函数不是虚函数,那么通过基类指针删除派生类对象时,调用的是基类的析构函数,导致派生类的资源没有被正确释放
  2. 代码如下:
#include <iostream>
using namespace std;class Base
{
public:virtual ~Base(){ // 虚析构函数cout << "基类 析构函数执行" << endl;}
};class Derived : public Base
{
public:~Derived() override{cout << "派生类 析构函数执行" << endl;}
};int main()
{Base *basePtr = new Derived;delete basePtr; // 先调用派生类的析构函数,再调用基类的析构函数return 0;
}
  1. 对象切片
    1. 如果通过 值传递(而非指针或引用)传递对象,会发生 对象切片,即派生类对象的派生部分会被切掉,变成一个基类对象。
#include <iostream>
using namespace std;class Base
{
public:virtual void show(){cout << "Base show" << endl;}
};class Derived : public Base
{
public:void show() override{cout << "Derived show" << endl;}
};void display(Base &obj) // 通过引用传递对象不会导致“对象切片”
// void display(Base obj)  // 值传递会导致“对象切片”
{obj.show();
}int main()
{Derived d;display(d);return 0;
}
  1. 对象传递最好是传递指针或者引用,直接进行值传递会导致对象切片:
#include <iostream>using namespace std;class Animal
{
public:virtual void sound(){cout << "Animal sound" << endl;}
};class Dog : public Animal
{
public:void sound() override{cout << "Dog barks" << endl;}
};int main(int argc, char const *argv[])
{Dog dog;dog.sound();  // 输出是Dog barksAnimal *basePtr = &dog;basePtr->sound();  // 输出是Dog barksAnimal &baseRef = dog;baseRef.sound();  // 输出是Dog barksAnimal baseObj = dog;baseObj.sound();  // 输出是Animal sound(这里产生了对象切片)return 0;
}

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

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

相关文章

主存储器——随机存取存储器RAM

静态RAM 双稳态触发器 一、工作特性 两种稳定状态&#xff1a; 双稳态触发器具有两个稳定的输出状态&#xff0c;通常表示为 0 和 1&#xff08;或低电平和高电平&#xff09;。这两个状态可以长期保持&#xff0c;即使在没有输入信号的情况下&#xff0c;也不会自发地改变。 例…

【分布式微服务云原生】消息队列全解析:原理、应用场景与主流MQ对比

消息队列全解析&#xff1a;原理、应用场景与主流MQ对比 摘要 在快速发展的软件架构中&#xff0c;消息队列&#xff08;MQ&#xff09;扮演着至关重要的角色。它不仅实现了系统间的异步通信&#xff0c;还提供了应用解耦、流量削峰等关键功能。本文将深入探讨消息队列的工作原…

初识TCP/IP协议

回顾上文 来回顾一下TCP协议的特性&#xff0c;有一道比较经典的题&#xff1a;如何使用UDP实现可靠传输&#xff0c;通过应用程序的代码&#xff0c;完成可靠传输的过程&#xff1f; 原则&#xff0c;TCO有啥就吹啥&#xff0c;引入滑动窗口&#xff0c;引入流量控制&#x…

面试金典题3.2

请设计一个栈&#xff0c;除了常规栈支持的pop与push函数以外&#xff0c;还支持min函数&#xff0c;该函数返回栈元素中的最小值。执行push、pop和min操作的时间复杂度必须为O(1)。 示例&#xff1a; MinStack minStack new MinStack(); minStack.push(-2); minStack.push(…

基于 Qwen2.5-0.5B 微调训练 Ner 命名实体识别任务

一、Qwen2.5 & 数据集 Qwen2.5 是 Qwen 大型语言模型的最新系列&#xff0c;参数范围从 0.5B 到 72B 不等。 对比 Qwen2 最新的 Qwen2.5 进行了以下改进&#xff1a; 知识明显增加&#xff0c;并且大大提高了编码和数学能力。在指令跟随、生成长文本&#xff08;超过 8K…

前台项目启动/打包报错 Error: error:0308010C:digital envelope routines::unsupported

在package.json中修改启动/打包语句 如图&#xff0c;我这里是打包时候报错&#xff0c;就在build里前面加上 set NODE_OPTIONS--openssl-legacy-provider && 再次打包&#xff0c;成功。

Unity 2D RPG Kit 学习笔记

学习资料&#xff1a; B站教学视频&#xff1a;https://www.bilibili.com/video/BV1dC4y1o7A5?p1&vd_source707ec8983cc32e6e065d5496a7f79ee6 2D RPG Kit Documentation.pdf文档 1、2D RPG Kit Documentation文档 1.1、Scenes/TitleScreen 开始菜单工程 1.2、https://it…

基于YOLOv8的智能植物监测机器人

摘要:针对传统的植物病害检测方法依赖专家的经验,耗时耗力,并且准确性受限于个人的水平等问题。文中提出无线通信模块采用HTTP协议来传输数据图片,采用SoC核心处理器实现了便携化,采用对射式红外避障传感器实现自动避障功能。以YOLOv8算法为控制核心,并添加注意力机制以提…

闭源与开源嵌入模型比较以及提升语义搜索效果的技术探讨

上图为执行语义搜索前的聚类演示 &#xff0c;嵌入技术是自然语言处理的核心组成部分。虽然嵌入技术的应用范围广泛&#xff0c;但在检索应用中的语义搜索仍是其最常见的用途之一。 尽管知识图谱等可以提升检索的准确率和效率&#xff0c;但标准向量检索技术仍然具有其实用价值…

「安装」 Windows下安装CUDA和Pytorch

「安装」 Windows下安装CUDA和Pytorch 文章目录 「安装」 Windows下安装CUDA和PytorchMac、Linux、云端Windows安装CUDA安装miniconda安装PyTorch测试总结 其他 Mac、Linux、云端 Mac、Linux、云端安装Miniconda和Pytorch的方法参考其他资料。 Windows 下面进行Windows下安装…

TDengine 流计算与窗口机制的深度解析:揭示计数窗口的关键作用

在 TDengine 3.2.3.0 版本中&#xff0c;我们针对流式计算新增了计数窗口&#xff0c;进一步优化了流式数据处理的能力。本文将为大家解读流式计算与几大窗口的关系&#xff0c;并针对新增的计数窗口进行详细的介绍&#xff0c;帮助大家进一步了解 TDengine 流式计算&#xff0…

基于Hive和Hadoop的病例分析系统

本项目是一个基于大数据技术的医疗病历分析系统&#xff0c;旨在为用户提供全面的病历信息和深入的医疗数据分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 Spark…

uniapp中实现评分组件,多用于购买商品后,对商品进行评价等场景

前言 uni-rate是uniapp框架中提供的一个评分组件。它可以用于用户评价、打分等场景。uni-rate组件可以根据设定的星星总数&#xff0c;展示用户评分的效果&#xff0c;用户可以通过点击星星或滑动星星的方式进行评分。同时&#xff0c;uni-rate组件也支持自定义星星图标、星星…

AI助手——合理利用AI写作的相关方法

引言 概述AI助手的出现与应用现状 AI助手的出现是随着人工智能技术的不断进步而逐渐成为现实。AI助手是利用人工智能技术开发的智能辅助工具&#xff0c;可以在多个领域提供帮助和支持。在写作领域&#xff0c;AI助手的应用越来越广泛。 AI助手可以帮助写作者更高效地完成文本…

CSS3 字体

CSS3 字体 CSS3字体是网页设计和开发中的一个重要方面&#xff0c;它允许设计师使用各种字体来增强网页的视觉效果和用户体验。在本文中&#xff0c;我们将探讨CSS3字体的基本概念、特性、使用方法以及最佳实践。 1. CSS3字体基本概念 CSS3字体是指使用CSS3样式表来控制网页…

express,生成用户登录后的 token

在 Node.js 中使用 Express 框架生成用户登录后的 token&#xff0c;通常会涉及到以下几个步骤&#xff1a; 设置 Express 应用&#xff1a;首先&#xff0c;你需要有一个基本的 Express 应用。安装必要的中间件&#xff1a;例如 jsonwebtoken&#xff08;JWT&#xff09;用于…

[leetcode]300_最长递增子序列

给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。 例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列 示例 1&#xff…

新品 | Teledyne FLIR IIS 推出Forge 1GigE SWIR 短波红外工业相机系列

近日&#xff0c;51camera的合作伙伴Teledyne FLIR IIS推出了新品Forge 1GigE SWIR 130万像素的红外相机。 Forge 1GigE SWIR系列的首款相机配备宽频带、高灵敏度的Sony SenSWIR™️ 130万像素IMX990 InGaAs传感器。这款先进的传感器采用5um像素捕捉可见光和SWIR光谱&#xff…

ip的类型有多少种?我想做大数据需要使用哪一种

IP地址主要分为两种类型&#xff1a; IPv4&#xff08;Internet Protocol version 4&#xff09;&#xff1a; 由32位二进制数组成&#xff0c;通常以四个十进制数表示&#xff08;例如&#xff1a;192.168.1.1&#xff09;。每个十进制数的范围是0到255。IPv4地址的总数量约为…