手记

C++11工程实践学习:从入门到初级应用

概述

本文介绍了C++11工程实践学习的基础知识,包括数据类型、控制结构、函数定义与调用等内容。文章还详细讲解了C++11的新特性,如智能指针、range-based for循环等。此外,文中还提供了项目组织与编译链接的实际案例,以及编码规范与最佳实践的指导。

C++11基础语法简介

数据类型与变量

在C++中,数据类型定义了变量可以存储的数据种类。C++提供了多种内置数据类型,包括整型、浮点型、字符型等。

整型

整型数据类型用于存储整数。C++11中常见的整型包括:

  • int: 用于存储整数。
  • long: 用于存储长整数。
  • short: 用于存储短整数。
  • long long: 用于存储非常大的整数。

示例代码:

#include <iostream>

int main() {
    int i = 10;
    long l = 1000000;
    short s = 200;
    long long ll = 1000000000000000000LL;
    std::cout << "int: " << i << "\nlong: " << l << "\nshort: " << s << "\nlong long: " << ll << std::endl;
    return 0;
}

浮点型

浮点型数据类型用于存储浮点数。C++11中常见的浮点型包括:

  • float: 单精度浮点数。
  • double: 双精度浮点数。
  • long double: 长双精度浮点数。

示例代码:

#include <iostream>

int main() {
    float f = 3.14f;
    double d = 3.14159;
    long double ld = 3.14159265358979323846264338327950288L;
    std::cout << "float: " << f << "\ndouble: " << d << "\nlong double: " << ld << std::endl;
    return 0;
}

字符型

字符型数据类型用于存储单个字符或字符串。C++11中常见的字符型包括:

  • char: 存储单个字符。
  • wchar_t: 存储宽字符。
  • char16_t: 存储UTF-16编码的字符。
  • char32_t: 存储UTF-32编码的字符。

示例代码:

#include <iostream>

int main() {
    char c = 'a';
    wchar_t wc = L'Ω';
    char16_t c16 = u'a';
    char32_t c32 = U'Ω';
    std::cout << "char: " << c << "\nwchar_t: " << wc << "\nchar16_t: " << c16 << "\nchar32_t: " << c32 << std::endl;
    return 0;
}

数组与指针

数组用于存储固定数量的相同类型的元素。指针用于存储变量的内存地址。

数组

数组的声明和初始化。

示例代码:

#include <iostream>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    for (int i = 0; i < 5; i++) {
        std::cout << "arr[" << i << "] = " << arr[i] << std::endl;
    }
    return 0;
}
指针

指针的声明和使用。

示例代码:

#include <iostream>

int main() {
    int x = 10;
    int* ptr = &x;
    std::cout << "x: " << x << "\nptr: " << ptr << "\nValue pointed by ptr: " << *ptr << std::endl;
    return 0;
}

控制结构(if, for, while)

控制结构在编程中的作用是控制程序的执行流程。C++11中常见的控制结构包括ifforwhile

if

if语句用于在满足一定条件时执行块代码。

示例代码:

#include <iostream>

int main() {
    int x = 10;
    if (x > 5) {
        std::cout << "x is greater than 5" << std::endl;
    }
    return 0;
}

for

for循环用于重复执行一段代码,直到满足特定条件为止。

示例代码:

#include <iostream>

int main() {
    for (int i = 0; i < 5; i++) {
        std::cout << "Iteration " << i << std::endl;
    }
    return 0;
}

while

while循环用于在条件为真时重复执行一段代码。

示例代码:

#include <iostream>

int main() {
    int i = 0;
    while (i < 5) {
        std::cout << "Iteration " << i << std::endl;
        i++;
    }
    return 0;
}

函数定义与调用

函数是程序的基本构建块,用于执行特定的任务。C++中的函数定义包括函数名、参数列表和返回类型。

函数定义

函数定义包括函数名、参数列表、返回类型和函数体。

示例代码:

#include <iostream>

int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(3, 4);
    std::cout << "Result: " << result << std::endl;
    return 0;
}

函数调用

函数调用通过指定函数名和参数列表来执行函数。

示例代码:

#include <iostream>

void printHello() {
    std::cout << "Hello, world!" << std::endl;
}

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

类与对象

类是面向对象编程的基础,用于定义对象的结构和行为。

类定义

定义一个简单的类。

示例代码:

#include <iostream>

class Person {
public:
    std::string name;
    int age;

    void setName(std::string n) {
        name = n;
    }

    void setAge(int a) {
        age = a;
    }

    void printInfo() {
        std::cout << "Name: " << name << "\nAge: " << age << std::endl;
    }
};

int main() {
    Person p;
    p.setName("Alice");
    p.setAge(30);
    p.printInfo();
    return 0;
}
C++11新特性介绍

智能指针

智能指针是自动管理内存的指针类型。C++11引入了std::unique_ptrstd::shared_ptr

  • std::unique_ptr: 保证指针唯一,不允许复制。
  • std::shared_ptr: 通过引用计数管理指针,允许多个指针共享同一资源。

示例代码:

#include <iostream>
#include <memory>

int main() {
    // unique_ptr
    std::unique_ptr<int> uptr(new int(10));
    std::cout << "unique_ptr: " << *uptr << std::endl;

    // shared_ptr
    std::shared_ptr<int> sptr(new int(20));
    std::cout << "shared_ptr: " << *sptr << std::endl;
    return 0;
}

range-based for循环

range-based for循环是C++11中的一种新语法,用于遍历容器中的元素。

示例代码:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    for (auto& value : vec) {
        std::cout << value << " ";
    }
    return 0;
}

auto关键字

auto关键字允许编译器根据变量的初始化表达式自动推断变量类型。

示例代码:

#include <iostream>
#include <vector>

int main() {
    auto vec = std::vector<int>({1, 2, 3, 4, 5});
    for (auto& value : vec) {
        std::cout << value << " ";
    }
    return 0;
}

lambda表达式

lambda表达式是C++11中的一种匿名函数。

示例代码:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {5, 3, 1, 4, 2};
    std::sort(vec.begin(), vec.end(), [](int a, int b) { return a < b; });
    for (auto& value : vec) {
        std::cout << value << " ";
    }
    return 0;
}

新的库函数

C++11引入了许多新的库函数,包括std::stringfindsubstr等。

示例代码:

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, world!";
    std::string substr = str.substr(7, 5);
    std::cout << "Substring: " << substr << std::endl;
    return 0;
}
工程实践入门

项目组织与目录结构

项目组织与目录结构对项目开发和维护非常重要。一个典型的项目结构可能如下:

my_project/
├── include/
│   └── my_project/
│       └── module1.h
│       └── module2.h
├── src/
│   └── module1.cpp
│   └── module2.cpp
├── main.cpp
├── CMakeLists.txt
└── README.md

编译与链接

编译和链接是将源代码转换为可执行文件的过程。C++项目通常使用Makefile、CMake等工具进行编译和链接。

示例代码(使用CMake):

cmake_minimum_required(VERSION 3.5)
project(MyProject)

add_executable(MyProject main.cpp src/module1.cpp src/module2.cpp)

示例代码(使用gcc):

g++ main.cpp src/module1.cpp src/module2.cpp -o my_project

常见编译器与IDE介绍

常见的C++编译器包括gccclangmsvc。常用的IDE包括Visual StudioCLionCode::Blocks等。

示例代码(使用gcc):

g++ main.cpp src/module1.cpp src/module2.cpp -o my_project
编码规范与最佳实践

代码风格指南

编码风格指南有助于保持代码的一致性和可读性。常见的编码风格指南包括:

  • 使用{}括号进行代码块的缩进。
  • 函数定义在头文件中声明,在源文件中实现。
  • 变量命名要有意义。
  • 使用注释进行代码说明。

示例代码:

// File: module1.h
#ifndef MODULE1_H
#define MODULE1_H

class Module1 {
public:
    void doSomething();
};

#endif

// File: module1.cpp
#include "module1.h"
#include <iostream>

void Module1::doSomething() {
    std::cout << "Doing something..." << std::endl;
}

错误处理与异常处理

错误处理和异常处理是程序开发的重要部分。常见的错误处理方法包括:

  • 使用try-catch块捕获异常。
  • 使用assert进行断言检查。
  • 使用std::optionalstd::expected进行返回值检查。

示例代码:

#include <iostream>
#include <stdexcept>
#include <optional>

std::optional<int> safeDivision(int a, int b) {
    if (b == 0) {
        return std::nullopt;
    }
    return a / b;
}

int main() {
    try {
        std::optional<int> result = safeDivision(10, 0);
        if (!result) {
            throw std::runtime_error("Division by zero");
        }
        std::cout << "Result: " << *result << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    return 0;
}

单元测试与持续集成

单元测试是验证代码正确性的有效方法。持续集成可以帮助自动化测试和部署过程。

示例代码(使用Google Test):

#include <gtest/gtest.h>

class Module1Test : public ::testing::Test {};

TEST(Module1Test, DivisionTest) {
    EXPECT_EQ(safeDivision(10, 2), 5);
    EXPECT_EQ(safeDivision(10, 0), std::nullopt);
}
实际案例解析

小项目开发流程

小项目开发流程通常包括以下几个步骤:

  1. 需求分析。
  2. 设计。
  3. 编码。
  4. 测试。
  5. 部署。

示例代码(使用CMake):

cmake_minimum_required(VERSION 3.5)
project(MyProject)

add_executable(MyProject main.cpp src/module1.cpp src/module2.cpp)

add_test(NAME MyProjectTest COMMAND MyProject)

常见问题解决方法

常见的编程问题包括内存泄漏、未初始化变量、异常处理不当等。

示例代码:

#include <iostream>
#include <stdexcept>
#include <optional>

std::optional<int> safeDivision(int a, int b) {
    if (b == 0) {
        return std::nullopt;
    }
    return a / b;
}

int main() {
    try {
        std::optional<int> result = safeDivision(10, 0);
        if (!result) {
            throw std::runtime_error("Division by zero");
        }
        std::cout << "Result: " << *result << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    return 0;
}
资源推荐与进阶学习

书籍与在线教程推荐

在线教程推荐:

  • 慕课网 提供了丰富的C++课程和教程。

书籍推荐:

  • 《Effective C++》 Scott Meyers
  • 《C++ Primer》 Lippman, Lajoie, and Moo

社区与论坛介绍

社区和论坛可以帮助开发者解决问题和交流经验,常见的社区和论坛包括:

0人推荐
随时随地看视频
慕课网APP