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 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 使用VS Code进行完整项目开发 -> 正文阅读

[C++知识库]使用VS Code进行完整项目开发

使用VS Code进行完整项目开发

参考链接: link

一、合理设置项目目录

案例:士兵突击
需求:
1.士兵有一把枪
2.士兵可以开火
3.士兵可以给枪装填子弹
4.枪能够发射子弹
5.枪能够装填子弹—“增加子弹数量”
开发:
开发枪类
开发士兵类
提取到的两个类的属性和动作如下图:
请添加图片描述

二、编写项目源文件

新建文件夹 vscode_c_learning_3,在终端用输入code . 用 vscode 打开新建的文件夹vscode_c_learning_3。
然后在该文件夹下创建清晰明了的目录结构
请添加图片描述
然后编写每个文件,如下:

//Gun.h:
//防止头文件重复包含
#pragma once
#include <string>
class Gun
{
public:
    Gun();
    ~Gun();
    Gun(std::string type)
    {
        this->_bullet_count = 0;
        this->_type = type;
    }
    void addBullet(int bullet_number);
    bool shoot();
private:
    int _bullet_count;
    std::string _type;

};
//Gun.cpp
#include "Gun.h"
#include <iostream>
Gun::Gun()
{

}
Gun::~Gun()
{

}

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

bool Gun::shoot()
{
    //不发射子弹
    if (this->_bullet_count <= 0)
    {
        std::cout << "There is no bullet!" << std::endl;
        return false;
    }
    //发射子弹
    this->_bullet_count -= 1;
    std::cout << "shoot successfully!" << std::endl;
    return true;
}
//Solider.h
#pragma once
#include <string>
#include "Gun.h"
class Solider
{
public:
    Solider();
    
    Solider(std::string name)
    {
        this->_name = name;
        this->_ptr_gun = NULL;
    }

    ~Solider();

    void addGun(Gun *ptr_gun);

    void addBulletToGun(int num);

    bool fire();

private:
    std::string _name;
    //在士兵类中包含枪类对象指针
    Gun *_ptr_gun;
};
//Solider.cpp
#include "Solider.h"
Solider::Solider()
{

}

void Solider::addGun(Gun *ptr_gun)
{
    this->_ptr_gun = ptr_gun;
}

void Solider::addBulletToGun(int num)
{
    this->_ptr_gun->addBullet(num);
}

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

Solider::~Solider()
{
    if(this->_ptr_gun == NULL)
    {
        return;
    }
    delete this->_ptr_gun;
    this->_ptr_gun = NULL;
}
//main.cpp
#include "Solider.h"
#include "Gun.h"
void test()
{
    Solider sanduo("xusanduo");
    sanduo.addGun(new Gun("AK47"));
    sanduo.addBulletToGun(20);
    sanduo.fire();
}

int main()
{
    test();
    return 0;
}

三、编译工程

3.1 使用 g++ 命令进行编译

利用快捷键 Ctrl + ` 打开终端,输入 ls 查看文件夹的文件情况;输入 tree . 来查看文件结构。
首先,通过在终端使用 g++ 直接编译:

g++ main.cpp src/Gun.cpp src/Solider.cpp -Iinclude -o myexe

编译成功后生成 myexe 可执行文件,运行 ./myexe 可以看到输出结果:shoot successfully!
也可以在 g++ 命令后面加上一些参数:

g++ main.cpp src/Gun.cpp src/Solider.cpp -Iinclude -o myexe -Wall -g -o2

3.2 使用 cmake 进行编译

首先,开始编写 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.0)

project(SOLIDERFIRE)

#在g++编译时,添加编译参数,比如-Wall可以输出一些警告信息
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O2 -Wall")

#添加头文件
include_directories(include)
#或者通过绝对路径来进行添加,include_directories(${CMAKE_SOURCE_DIR}/include)
#其中${CMAKE_SOURCE_DIR}就是VSCODE_C_LEARNING_3这个文件夹的绝对路径

add_executable(my_cmake_exe main.cpp src/Gun.cpp src/Solider.cpp)

编译完成后,在终端完成编译:

mkdir build
cd build
cmake ..
make

这时如果更改以下main.cpp,然后在终端重新输入 make 命令重新编译,此时可以看到系统只会对更改的文件进行重新编译,这对于一个大型工程来说是非常节约时间的。

四、配置VS Code的 json 文件并调试项目

接下来对工程进行调试。调试时要进行launch.json和tasks.json的编写
请添加图片描述
然后选择第一个 C++(GDB/LLDB),然后选择第一个 g++:生成和调试活动文件,
可以得到如下 launch.json 模板:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - 生成和调试活动文件",
            "type": "cppdbg",
            "request":"launch",
            "program":"${fileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启动整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: g++ build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

其中最重要的是: 1.“program”:代表了要调试的可执行文件的绝对路径2.“preLaunchTask”:指的是在调试之前要做一个task
因此,需要对这两个参数进行更改,编写 launch.json文件,
其中"cwd": " w o r k s p a c e F o l d e r " 中 " {workspaceFolder}"中" workspaceFolder""{workspaceFolder}"代表当前工程文件夹的顶层目录,
然后先将"preLaunchTask"注释掉,不进行更改

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

更改完的 launch.json 文件:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - 生成和调试活动文件",
            "type": "cppdbg",
            "request":"launch",
            "program":"${workspaceFolder}/build/my_cmake_exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启动整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            //"preLaunchTask": "C/C++: g++ build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

然后到目前为止就可以进行调试工作了。
打开终端,在 build 文件夹下重新 make 下,然后在 main.cpp中打个端点,利用快捷键 F5 进行调试。
请添加图片描述
可以看出,成功命中断点。
请添加图片描述
在单步调试中发现有时会单步进入不了,可能是由于编译时set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -g -O2 -Wall”)中 -g 和 -O2 发生冲突导致。因此将这两个删除,然后再加一句,更改完的 CMakeLists.txt 如下:

cmake_minimum_required(VERSION 3.0)

project(SOLIDERFIRE)

#在g++编译时,添加编译参数,比如-Wall可以输出一些警告信息
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")

#一定要加上这句话,加上这个生成的可执行文件才是可以Debug的,不然不加或者是Release的话生成的可执行文件是无法进行调试的
set(CMAKE_BUILD_TYPE Debug)

#添加头文件
include_directories(include)
#或者通过绝对路径来进行添加,include_directories(${CMAKE_SOURCE_DIR}/include)
#其中${CMAKE_SOURCE_DIR}就是VSCODE_C_LEARNING_3这个文件夹的绝对路径

add_executable(my_cmake_exe main.cpp src/Gun.cpp src/Solider.cpp)

重新 make,然后再调试。这时 Debug 功能正常,但不进入功能也正常了。这时为什么尼? 因为原来 CMakeLists.txt 中有个 -O2 的选项,这个选项会帮助优化代码,这会导致在调试过程中出现意料不到的效果。
接着,打开 launch.json 文件中的 “preLaunchTask”。

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - 生成和调试活动文件",
            "type": "cppdbg",
            "request":"launch",
            "program":"${workspaceFolder}/build/my_cmake_exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启动整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: g++ build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

然后要配置 tasks.launch。点击 选项栏 Terminal->Configure Default Build Task,然后随便选择一个,建立一个 task.json 文件。
请添加图片描述
将 tasks.json 文件中内容删除,替换为下面的内容:

{
	"version": "2.0.0",
	"options":{
		"cwd": "${workspaceFolder}/build"   //指明在哪个文件夹下做下面这些指令
	},
	"tasks": [
		{
			"type": "shell",
			"label": "cmake",   //label就是这个task的名字,这个task的名字叫cmake
			"command": "cmake", //command就是要执行什么命令,这个task要执行的任务是cmake
			"args":[
				".."
			]
		},
		{
			"label": "make",  //这个task的名字叫make
			"group": {
				"kind": "build",
				"isDefault": true
			},
			"command": "make",  //这个task要执行的任务是make
			"args": [

			]
		},
		{
			"label": "Build",
			"dependsOrder": "sequence", //按列出的顺序执行任务依赖项
			"dependsOn":[				//这个label依赖于上面两个label
				"cmake",
				"make"
			]
		}
	]
}

然后要在 launch.json文件中改一下 “preLaunchTask” 指明的名字,从 tasks.json 中可以看出,最后一个 label 叫做 “Build”, 因此将launch.json文件中 “preLaunchTask” 指明的名字改为 “Build”。

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - 生成和调试活动文件",
            "type": "cppdbg",
            "request":"launch",
            "program":"${workspaceFolder}/build/my_cmake_exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启动整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "Build",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

至此,launch.json 和 tasks.json 全部配置完成。至此,就可以完成自动化的调试了。
举例:
比如在 main.cpp 中随便加一句:
请添加图片描述
然后,在下一句处打断点,F5运行,发现直接调到断点处且这句输出直接打印出来。
这说明在修改工程文件后再也不用手动编译后再调试,而是直接对工程修改后直接打断点进行调试。系统会自动进行编译和调试。(就是通过launch.json中的 "preLaunchTask"完成的,而这个就是 tasks.json 完成的)
详情如下图所示:
请添加图片描述
总结:在一个工程中要建两个 json 文件,一个是 launch.json 文件, 一个是 tasks.json 文件。
launch.json 的模板如下:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - 生成和调试活动文件",
            "type": "cppdbg",
            "request":"launch",
            "program":"${workspaceFolder}/build/my_cmake_exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启动整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "Build",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

需要更改 “program” 和 “preLaunchTask”。
tasks.json 的模板如下:

{
	"version": "2.0.0",
	"options":{
		"cwd": "${workspaceFolder}/build"   //指明在哪个文件夹下做下面这些指令
	},
	"tasks": [
		{
			"type": "shell",
			"label": "cmake",   //label就是这个task的名字,这个task的名字叫cmake
			"command": "cmake", //command就是要执行什么命令,这个task要执行的任务是cmake
			"args":[
				".."
			]
		},
		{
			"label": "make",  //这个task的名字叫make
			"group": {
				"kind": "build",
				"isDefault": true
			},
			"command": "make",  //这个task要执行的任务是make
			"args": [

			]
		},
		{
			"label": "Build",
			"dependsOrder": "sequence", //按列出的顺序执行任务依赖项
			"dependsOn":[				//这个label依赖于上面两个label
				"cmake",
				"make"
			]
		}
	]
}

其中最后一个 label 的名字要和 launch.json 中 “preLaunchTask” 的名字一致。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 11:37:29  更:2022-04-28 11:37:47 
 
开发: 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/23 22:30:42-

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