IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> VScode C++ 开发 (七):实战篇及Vscode调试 -> 正文阅读

[开发工具]VScode C++ 开发 (七):实战篇及Vscode调试

1. 项目介绍

案例:士兵突击

需求:

(1) 士兵 许三多 有一把枪,叫做 AK47
(2) 士兵 可以 开火
(3) 士兵 可以 给枪装填子弹
(4) 能够 发射 子弹
(5) 能够 装填子弹—增加子弹数量

开发:

  • 开发枪类
  • 开发士兵类
    在这里插入图片描述

2. 合理设置项目目录

2.1 新建文件夹

  • 新建Include文件夹存放.h头文件
  • 新建src文件夹存放.cpp源文件

3 创建类

3.1 创建Gun类

创建Gun.hGun.cpp

  • 编写Gun.h头文件,定义Gun类的接口
#pragma once
#include <string>

using namespace std;
class Gun
{
public:
	Gun(string type);
	void addBullet(int bullet_num);
	bool shoot();

private:
	int _bullet_count;
	string _type;
};

编写Gun.cpp源代码,实现Gun类的接口

#include "Gun.h"
#include <iostream>
using namespace std;
Gun::Gun(string type){
   this -> _bullet_cout=0;
   this ->_type=type;
}

void Gun::addBullet(int bullet_num)
{
 this->_bullet_count += bullet_num;
}

bool Gun::shoot()
{
	if (this -> _bullet_count <=)
	{
		cout <<"There is no bullet" <<endl;
		return false;
	}
	this -> _bullet_count -=1;
	cout << "shoot successfully!"<<endl;
	return true;
}

3.2 创建士兵类Soldier

创建Soldier.hSoldier.cpp

  • 编写Soldier.h头文件,定义Soldier类的接口
#pragma once
#include <string>
#include "Gun.h"

using namespace std;
class Soldier
{
public:
	Soldier(string name);
	~Soldier();
	void addBullerToGun(int num);
	void addGun(Gun *ptr_gun);
	bool fire();

private:
	string _name;
	Gun* _ptr_gun;
};
  • 编写Soldier.cpp源代码,实现Soldier类的接口
#include "Soldier.h"
using namespace std;
Soldier::Soldier(string name)
{
	this -> _name = name;
	this -> _ptr_gun = nullptr;
]

void Soldier :: addGun(Gun *ptr_gun)
{
	this ->_ptr_gun = ptr_gun;
}
void Soldier ::addBulletToGun(int num)
{
	this -> _ptr_gun ->addBullet(num);
}

bool Soldier::fire()
{
	this ->_ptr_gun ->shoot();
}

Soldier::~Soldier()
{
	if (this -> _ptr_gun == nullptr)
	{
		return ;
	}
	delete this -> _ptr_gun;
	this -> _ptr_gun = nullptr;
}

3.3 创建main函数

新建main.cpp文件,并编写代码

#include "Gun.h"
#include "Soldier.h"

void test()
{
	Soldier sanduo("xusanduo");
	sanduo.addGun(new Gun("AK47"));
	sanduo.addBullerToGun(20);
	sanduo.fire();
}
int main()
{
	test();
	return 0;
}

完整的代码结构如下:
在这里插入图片描述

4. 编译

4.1 g++方式编译

  • 执行如下命令,进行g++编译
g++ main.cpp src/Soldier.cpp src/Gun.cpp -Iinclude -o myg++exe  #-Iinclude 表示头文件在include目录中  -o 输出文件  
  • 运行可执行文件
./myg++exe
  • 执行结果显示:
shoot successfully!

编译可增加其他可选项如-Wall(显示警告信息), -g(调试格式) ,-O2(对代码进行优化)

g++ main.cpp src/Soldier.cpp src/Gun.cpp -Iinclude -o myg++exe -Wall -g -O2

4.2 cmake方式编译

4.2.1 编写CMakeLists.txt

cmake_minimum_required(VERSION 3.0) #可在终端输入 cmake --version 查看版本,一般3.0基本都满足要求
project(SOLDIERFIRE)  #项目名称
include_directories(${CMAKE_SOURCE_DIR}/include)  #包含include头文件夹路径
add_executable(my_camke_exe  main.cpp  src/Gun.cpp src/Soldier.cpp)

如果需要增加一些编译选项如:-O2,-d ,-Wall,-std11++等,可以在project命令后增加一行命令:

set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS}  -g  -O2 -Wall")  # 原来的编译选项${CMAKE_SOURCE_DIR}后面追加 -g -O2 -Wall选项

4.2.2 编译

mkdir build
cd build
cmake ..  # ..指定到cMakeLists.txt 所在目录

在这里插入图片描述
编译成功,生成了makefile文件,然后执行make命令,生成可执行文件

make

在这里插入图片描述
可以通过编写build.sh来完成编译过程,build.sh的内容如下:

# !/bin/bash
if [ ! -d build ] ; then
	mkdir build
fi
cd build
cmake ..
make -j4

执行bash就可以完成编译,该方式编译可减少重复工作

bash build.sh

4.2.3 运行可执行文件

./my_cmake_exe

结果:shoot successfully!

注:当修改了代码,可以执行make进行重新编译
重新编译

make

cmake的方式重新编译只会对修改的文件,重新编译,这对于大型的项目,是非常节约时间的

5. 调试

(1) 点击vscode调试按钮,点击create a launch.json file ,因为在调试之前需要配置lanuch.jsontask.json文件

在这里插入图片描述
(2) 选择 C++(GDB/LLDB),然后在选择g++ 生成和调试活动文件`
在这里插入图片描述
(3) 弹出launch.json文件
在这里插入图片描述

其中programpreLaunchTask命令是两条非常重要的命令,后续需要更改这两条命令。
(4) 修改lanuch.json文件,这里先只修改lanuch.json文件,调试看看

由于之前生成了cmake 版和g++版可执行文件,可执行文件的位置如下所示:

在这里插入图片描述
先调试build文件下cmake 编译的my_cmake_exe文件,修改program为目标可执行文件的绝对路径

"program":"${workspaceFolder}/build/my_cmake_exe",

其中preLaunchTask先暂时不修改,进行注释掉,修改后的launch.json文件如下

{
  "version": "0.2.0",
  "configurations":[
  {   
  	  "name":  "g++ - 生成和调试活动文件",
	  "type": "cppdbg",
	  "request":"launch",
	  "program":"${workspaceFolder}/build/my_cmake_exe",
	  "args":[],
	  "stopAtEntry":false,
	  "MIMode":"gdb",
	  "setupCommands":[
	  	{
	    	"description":"为 gdb 启用整齐打印",
	    	"text":  "-enable-pretty-printing",
	    	"ignoreFailures":true
	    }
	 ],
	  
	  //"preLaunchTask":"C/C++ g++ build active file",
	  "miDebuggerPath":"/usr/bin/gdb"
   }
  ]
}

(4) 重新编译

cd build
make

(5) 设置断点,并在Vscode中按F5进行调试
在这里插入图片描述
:在调试过程中,debug 进入不了代码内部,可能是CMakeLists.txt中的编译选项的问题,如下:

set(CMAKE_CXX_FLAGS "{CMAKE_CXX_FLAGS} -g -O2 -Wall")

选项发生了冲突,-O2会对代码进行优化,-g需要输出带调试信息,因此需要修改CMakeLists.txt,去掉-g -O2 ,添加set(CMAKE_BUILD_TYPE Debug)

cmake_minimum_required(VERSION 3.0) #可在终端输入 cmake --version 查看版本,一般3.0基本都满足要求
project(SOLDIERFIRE)  #项目名称
set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS}  -Wall")  # 原来的编译选项${CMAKE_SOURCE_DIR}后面追加 -g -O2 -Wall选项
set(CMAKE_BUILD_TYPE Debug) # 如果是Release生成的文件是无法被调试的
include_directories(${CMAKE_SOURCE_DIR}/include)  #包含include头文件夹路径
add_executable(my_camke_exe  main.cpp  src/Gun.cpp src/Soldier.cpp)

重新make一下,就可以调试了

(6) 修改tasks.json文件
点击 VScode工具栏中的Terminal ->Configure Task,重新修改tasks.json文件,修改好的tasks.json文件如下:

{
	"version": "2.0.0",
	"options":{
		"cwd": "${workspaceFolder}/build"
	},
	"tasks":[
		{
			"type":"shell",
			"label":"cmake",
			"command":"cmake",
			"args":[
					".."
				]
		},
		
		{
			"label":"make",
			"group":{
					"kind":"build",
					"isDefault":true
				},
			"command":"make",
			"args":[
				]
		},
		
		{
			"label":"Build",
			"dependsOrder":"sequence",  //按列出的顺序执行任务依赖项
			"dependsOn":[
					"cmake",
					"make"
				]
		}
	]
}

此时可将launch.json 中的 preLaunchTask改为

"preLaunchTask":"Build"  // Build 实在tasks.json中定义的序列任务名

完整的launch.json如下:

{
  "version": "0.2.0",
  "configurations":[
  {   
  	  "name":  "g++ - 生成和调试活动文件",
	  "type": "cppdbg",
	  "request":"launch",
	  "program":"${workspaceFolder}/build/my_cmake_exe",
	  "args":[],
	  "stopAtEntry":false,
	  "MIMode":"gdb",
	  "setupCommands":[
	  	{
	    	"description":"为 gdb 启用整齐打印",
	    	"text":  "-enable-pretty-printing",
	    	"ignoreFailures":true
	    }
	 ],
	  
	  "preLaunchTask":"Build",
	  "miDebuggerPath":"/usr/bin/gdb"
   }
  ]
}

(7) 完成launch.jsontasks.json后,即可实现自动化调试功能,不需要手动编译可执行文件
测试
在main.cpp中添加一行代码,如下:

#include "Gun.h"
#include "Soldier.h"
#include <iostream>

using namespace std;
void test()
{
	Soldier sanduo("xusanduo");
	sanduo.addGun(new Gun("AK47"))
	sanduo.addBulletToGun(20);
	sanduo.fire();
}

int main(int argc,char **argv)
{
	cout << "This is a test string ..." <<endl;  //新增一行改代码
	test();
	return 0;
}

增加一行新代码后不需要手动编译可执行文件,可直接进行调试,系统通过preLaunchTask自动帮忙编译

参考

B站UP主:xiaobing1016

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-01-12 00:12:52  更:2022-01-12 00:15:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 12:46:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码