C++基础知识1
git基础
SVN(集中式版本控制器)和git(分布式版本控制器)区别
SVN本地没有仓库信息存储代码,代码信息全部存储到云端。本地代码全部push到云端。
git 好处:版本库对提交的代码保存其版本提交记录; 每次提交代码push之前先拉取代码pull,再次push时只会push经过改动的地方;
git命令
创建本地代码库(只执行一次) 若有多个.git则会出现ERROR: 500
git init
查看工作区状态
git status (分支:开发版、测试版、发布版)
添加文件到缓存区
git add<修改的文件>
eg:git add 1.cpp添加 git rm --cache 1.cpp移除 git add . 全部添加 git rm *.后缀
git rm -r --cache . 删除本地所有缓存信息,用于重新上传
提交修改
git commit -m "文件描述"
git log 查看提交日志
提交规范:
【项目:COM组件练习】【ones:3】【改动:xxxxxxxxxxxxx】
git远程仓库指令
上传: git push
添加 / 删除
git remote add / remove
git remote add origin https://xxxxxxxxxxxxxxxxxxx
git push -u origin master
origin可以理解为上传地址的赋值变量 master 上传的分支
若发现本地和云端的信息不一致 重新删除本地缓存并上传 git rm -r --cache .
查看远程代码 git remote -v
拉代码
克隆远程仓库: git clone https://xxxxxxxxxxxxxxxxxxxxx
向服务器远程访问 git remote show origin
云端和本地不一致,需要拉取 git pull .
git上传流程 & 错误代码及解决
在一个新的文件夹里 git init
创建.git缓存目录 (只一次)
保证用户名和邮箱与git.cn中一致
git config --glabol user.name "wangjie_2"
git config --glabol user.email [email protected]
纯文本文件.gitignore
与.git文件在同级目录下,过滤规则为
.vs
Debug/
*.user
git add .
添加所有文件到缓存目录中
git rm -r --cache .
删除本地所有缓存信息,用于重新上传,再重新 git add .
git status
查看缓存目录中文件状态
git commit -m "【项目:删除数组元素】【ones: 1】【改动:第一次上传】"
添加注释信息
git remote add origin https://git.wpsit.cn/hubu-2023-cpp-tasks/wangjie_2.git
远程连接
git push -u origin master
上传
其他命令
git config --list 查看信息
git clone https://url 克隆代码
git log 查看提交历史
错误信息1:
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'https://git.wpsit.cn/hubu-2023-cpp-tasks/wangjie_2.git'
主要原因是gitee中的README.md文件不在本地代码目录中
输入 git pull --rebase origin master
命令将README.md拉到本地,
再 git push -u origin master
上传
错误信息2:
HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large
错误原因:http的413错误码是请求体太大,gitignore
未发挥作用
面向对象基础
C++规范
命名规范
驼峰 类中成员变量 m_ 开头 类名首字母大写 成员方法名首字母小写
拷贝构造
默认拷贝构造
构造函数名与类名相同
浅拷贝:问题1:两个指针指向一块内存 问题2:内存泄漏
深拷贝和浅拷贝
浅拷贝:
浅拷贝只拷贝了对象的引用,而地址不变。
问题
用户未定义拷贝构造函数,则会调用默认的拷贝构造函数。拷贝构造函数的参数类型是本类的引用。
发生浅拷贝、默认复制构造函数等问题会导致发生段错误,会连续调用两次析构函数去释放同一个地址。
因此在大多数使用的时候,用户要自己创建拷贝构造函数,需要自己释放堆区空间。
//用户自定义拷贝构造函数,在浅拷贝的基础上实现写时拷贝 【浅拷贝执行系统提供的默认构造函数】
KCopyable::KCopyable(const KCopyable& t)
{
//在使用浅拷贝时,通过修改一个对象的数据成员的值也会修改另一个对象的数据成员的值。
m_pRefCout = t.m_pRefCout;
}
浅拷贝总结:
创建一个新对象,然后将当前对象的非静态字段复制到该对象
若字段是一个值,则直接对该字段复制;
若字段是引用类型,则复制引用但不复制引用的对象,也就是只复制这个引用类型的地址。(原始对象及其副本引用同一个对象,也就是两个地址指向同一个内存的内容)
深拷贝
给每个对象独立分配资源,保证多个对象之间不会因共享资源而造成多次释放造成程序崩溃问题
在拷贝对象时,在堆上分配新的内存空间来存储数据成员的值,这样使得两个对象之间互不干扰。
//用户自定义拷贝构造,,若是引用计数类存在赋值操作,需要使用深拷贝单独处理。
KReferenceCount::KReferenceCount(const KReferenceCount& t)
{
m_paddr = new int;
*m_paddr = *t.m_paddr;
}
//当执行obj3 = obj2的时候,此时会触发=运算符。需要我们手动处理
KReferenceCount& KReferenceCount::operator=(const KReferenceCount& t)
{
if (this != &t)
{
delete m_paddr;
m_paddr = new int;
*m_paddr = *t.m_paddr;
}
return *this;
}
复用了构造函数来实现拷贝构造函数。并且重载了=符号,防止隐式赋值。
浅拷贝的问题本质在于析构函数多次释放堆区内存
深拷贝和浅拷贝的扩散
问:foreach如果使用auto来循环,是深拷贝还是浅拷贝,怎么避免问题发生。
答:首先区分基本类型和引用类型的区别:
基本类型:一般都是数据值,赋值给多个对象之间不会产生关联
引用类型:在赋值时赋的是值地址,一般都是指针地址。就是引用类型变量在内存中保存的内容。
因此如果foreach的list对象是基本类型,auto是可以使用的,会自动判断对象并且赋值;
若是引用类型,浅拷贝会复制对象的引用来访问;
深拷贝的触发条件是:list对象是内部含有指向堆的指针,也就是用户自己创建的类的对象,自 己开辟的堆区内存。
写时拷贝
(13条消息) 六、C++语言进阶:写时拷贝技术_c++写时拷贝__深蓝.的博客-CSDN博客
字符串发生改变时,应用写时拷贝。
//当执行obj3 = obj2的时候,此时会触发=运算符。需要我们手动处理
KReferenceCount& KReferenceCount::operator=(const KReferenceCount& t)
{
if (this != &t)
{
delete m_paddr;
m_paddr = new int;
*m_paddr = *t.m_paddr;
}
return *this;
}
智能指针
全局变量 & 全局函数
依赖关系:
全局变量问题:构造函数依赖全局变量;
解决方法: 手动创建
//定义全局函数,通过手动调用方式创建对象。
//静态变量定义在函数中,使用时才会创建,可以起到节省内存的作用。
//静态变量只会定义一次,不会重复定义
TryClassSecond& getClassObj()
{
static TryClassSecond g_secondObj;
return g_secondObj;
}
全局函数:
调试classfirst classsecond
静态变量
静态成员函数 static关键字 【 static int XXXX 】
使用较多:通过类名直接引用静态成员函数 语法【类 : : 静态成员函数】
RAII机制
RAII ( Resource Acquisition Is Initialization)资源获取就是初始化
智能指针
智能指针:智能/自动化的管理指针所指向的动态资源的释放;
通过对象管理指针,在构造对象的时候完成资源的分配及初始化,在析构对象的时候完成资源的清理工作。
解决问题:申请了内存,在使用后忘记释放
unique_ptr
详见 knowUniquePtr.md
unique_ptr对对象的所有权专一
每个unique_ptr指针都肚子拥有对其所指堆内存空间的所有权,一旦放弃堆内存的所有权则立即释放回收。
不允许进行拷贝构造和赋值操作
share_ptr(常用)
详见 knowSharePtr.md
智能指针share_ptr 的原理简单来说,就是做引用计数,多一个引用就加1,少一个引用,就减去1,当引用计数为0,则认为没有人用了,就主动调用delete,完成对象释放
。
共享资源的智能指针,允许多个指针指向一个对象
引用指针计数的原理
环的问题
问题描述:
解决方案:将其中一个类改为weak_ptr,weak_ptr和share_ptr相同但其构造和析构不会引起引用计数的增加和减少,不会影响生命周期。