当前位置: 首页 > news >正文

C++23 高级编程 Professional C++, Sixth Edition(一)

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、C++速成
  • 二、string和 string_view
  • 三、程序设计的一般方法
    • 类之间的关系
    • 设计可重用代码


前言

g++ -std=c++2b -o <executable_name> <source1.cpp> [source2.cpp ...]
-std=c++2b 表示启用对c++23功能的支持,当GCC完全兼容c++23后可改为 -std=c++23
-fmodules-ts 启用模块支持

编译标准库头文件<iostream>和<string>:

g++ -std=c++2b -fmodules-ts -xc++-system-header iostream
g++ -std=c++2b -fmodules-ts -xc++-system-header iostream
g++ -std=c++2b -fmodules-ts -xc++-system-header string

编译模块接口文件:

g++ -std=c++2b -fmodules-ts -c -x c++ AirlineTicket.cppm

编译应用代码:

g++ -std=c++2b -fmodules-ts -o AirlineTicket AirlineTicket.cpp AirlineTicketTest.cpp AirlineTicket.o

一、C++速成

// c++20
import std;
import <print>;std::println("hello this is {}", "rust");std::cout << std::format("Oh are {} ways I l u.", 219) << std::endl;

字面量:
整数,浮点数,字符,字符串

c++23中引入的扩展浮点数类型

类型说明字面量后缀
std::float16_tIEEE754 标准的16位格式F16, f16
std::float32_tIEEE754 标准的32位格式F32, f32
std::float64_tIEEE754 标准的64位格式F64, f64
std::float128_tIEEE754 标准的128位格式F128, f128
std::bfloat16_t用于某些人工智能领域BF16, bf16

枚举

enum class PieceType: std::uint32_t {King = 1,Queen,Rook = 10,Pawn
};
PieceType piece { PieceType::King };
int underlying_value {std::to_underlying(piece)};

if-else

if ( <initializer>; <condi_expression>) {<if_body>
} else if (<else_if_expression>) {<else_if_body>
} else {<else_body>
}switch (<initializer>; <expression>) { <body> }case Custom:value = 84;[[fallthrough]];  // 告诉编译器某个 fallthrough 是有意为之// 阻止编译器发出警告

属性
指定内存对齐字节

#pragma pack(1)  // 1字节内存对齐(必须是2的指数)
#pragma pack()   // 默认对齐
  1. [[nodiscard]]
//可用于有一个返回值的函数,以使编译器在该函数被调用却没有对返回的值进行任何处理时发出警告
[[nodiscard]] int func() { return 42; }
// [[nodiscard("some explanation")]]func();  
warning C4834: discarding return value of function with 'nodiscard' attribute
  1. [[maybe_unused]]
禁止编译器在未使用某些内容时发出警告
int func(int param1, [[maybe_unused]] int param2);
  1. [[noreturn]]
它永远不会将控制权返回给调用点
[[noreturn]] void force_terminate() {exit(1); // abort();
}
  1. [[deprecated]]
将某些内容标记为已弃用
[[deprecated("Unsafe function, please use xyz")]] void func();
  1. [[likely]], [[unlikely]]
int value { /* ... */ };
if (value > 11) [[unlikely]] { /* Do something ... */ }
else { /* Do something else ... */ }
switch (value)
{
[[likely]] case 1:
// Do something ...
break;
case 2:
// Do something ...
break;
[[unlikely]] case 12:
// Do something ...
break;
}

std::optional

#include <optional>
std::optional<int> get_data(bool giveit)
{if (giveit) return 43;return std::nullopt; // return {}
}std::optional<int> data1{ get_data(true) };
std::optional<int> data2{ get_data(false) };
if (data1) { data1.value(); }
if (data2.has_value()) { *data2; }
data2.value_or(0);

初始化列表

import std;
using namespace std;
int sum(initializer_list<int> values)
{int total { 0 };for (int value : values) {total += value;}return total;
}int a { sum({ 1, 2, 3 }) };
int b { sum({ 10, 20, 30, 40, 50, 60 }) };

作为面向对象语言的 C++
ticket.cppm

export module airline_ticket;import <string>;export class AirlineTicket 
{public:AirlineTicket()  = default;~AirlineTicket() = default;double calculate_price_in_dollars();std::string get_passenger_name();void set_passenger_name(const std::string& name);int get_number_of_miles();// void set_number_of_miles(int miles);bool has_elite_super_rewards_status();void set_has_elite_super_rewards_status(bool status);private:std::string passenger_{0};int number_{0};bool has_elite_{false};};int AirlineTicket::get_number_of_miles()
{return 1;
}double AirlineTicket::calculate_price_in_dollars()
{if (has_elite_super_rewards_status()) return 0;return get_number_of_miles() * 0.1;
}
std::string AirlineTicket::get_passenger_name()
{return passenger_;
}
void AirlineTicket::set_passenger_name(const std::string& name)
{passenger_ = name;
}
bool AirlineTicket::has_elite_super_rewards_status()
{return has_elite_;
}
void AirlineTicket::set_has_elite_super_rewards_status(bool status)
{has_elite_ = status;
}
g++ -std=c++23 -fmodules-ts -c -x c++ ticket.cppm

main.cpp

import <vector>;
import <print>;
import airline_ticket;
using namespace std;
int main() {vector v{1,2,3,4};println("size: {}", v);AirlineTicket al;al.set_passenger_name("david.smith");println("{}", al.get_passenger_name());}

const

1. const 修饰类型
const int* p;
int const* p;int * const p {nullptr};const int * const p {new int(4)};2. const成员函数
3. 

结构化绑定

pair my_pair {"hello", 5};
auto [the_string, the_int] {my_pair};auto& [the_string, the_int] {my_pair};
const auto& [the_string, the_int] {my_pair};

auto
使用 auto 推断类型时去除了引用和 const 限定符。

int i {32};auto p {&i};         // int* p
const auto p1 {&i};  // int* const p1
auto const p2 {&i};  // int* const p2
const auto* p3 {&i}; // const int* p3
auto* const p4 {&i}; // int* const p4
const auto* const p5 {&i};  // const int* const p5;

decltype
未去除引用和const限定符

二、string和 string_view

c++20 三向比较运算符

string a {"ab"};
string b {"bc"};
auto result { a <=> b };
if (is_gt(result)) { println("greater"); }
if (is_lt(result)) { println("less"); }
if (is_eq(result)) { println("equal"); }

有用的转换函数

to_string()
stoi()
stol()
stoul()
stoll()
stoull()
class string_view 
{
public:const char* ptr;size_t size;
};// string_view 字面量
using namespace std::literals::string_view_literals;
" this is string view\n"sv;inline constexpr basic_string_view<char>operator""sv(const char* __str, size_t __len) noexcept{ return basic_string_view<char>{__str, __len}; }

c++23后 format(), print(), println()的格式字符串必须是编译期常量,以便编译器可在编译期检查字符串中是否有任何语法错误。否则需要使用std::vprint_unicode()或 std::vprint_nonunicode()

int a = 89;
// 运行时可能抛出std::format_error异常
vprint_unicode(GetLocalizedFormat(language), make_format_args(a, a));

三、程序设计的一般方法

  1. 将程序划分为子系统,并捋清楚各子系统之间的关系
  2. 选择线程模型
  3. 指定每个子系统的类层次结构
  4. 指定每个子系统的类、数据结构、算法和模式
    抽象:将接口和实现分离。从用户的观点确定接口,决定想让组件做什么,然后决定如何选择数据结构和算法。
    重用:
  5. 为每个子系统指定错误处理

类之间的关系

主要有两类:有一个(has a) ; 是一个(is a)

  1. 有一个
    A有一个B,或者A包含一个B,某个类是另一个类的一部分,即某个类是另一个类的数据成员
    • 聚合: 通过聚合,当聚合器被销毁时,聚合对象(组件)可以继续存在。如,动物园和里面的动物。
    • 组合:对于组合,如果由其他对象组成的对象被销毁时,那么这些其他对象也会被销毁。如何包含按钮的窗口对象被销毁,这些按钮对象也将被销毁。
  2. 是一个(继承)

优秀的面向对象层次结构:

  • 使类之间存在有意义的功能联系
  • 将共同的功能放入基类,从而支持代码重用
  • 避免子类过多地重写父类的功能,除非父类是一个抽象基类

设计可重用代码

SOLID原则

SOLIDdescription
SSingle Responsibility Principle,单一职责原则。单个组件应当具有单独、明确定义的责任,不应当与无关的功能组合在一起
OOpen/Closed Principle,开放/关闭原则。一个类对扩展应当是开放的,但对修改时关闭的,可扩展、不修改已有实现
LLiskov Substitution Principle,里氏替换原则。对于一个对象而言,应当能用该对象的子类型替代该对象的实例
IInterface Segregation Principle,接口隔离原则。接口应当简单清楚,不要使用过于宽泛的通用接口,最好使用多个较小的、明确定义的、责任单一的接口
DDependency Inversion Principle,依赖倒置原则。使用接口倒置依赖关系。依赖注入是支持依赖倒置原则的一种方式

http://www.dtcms.com/a/457553.html

相关文章:

  • Verilog和FPGA的自学笔记3——仿真文件Testbench的编写
  • 记录gitee的使用
  • 动态业务流程的案例管理标准(CMMN)
  • 广东门户网站建设哪个网站有适合小学生做的题
  • .NET周刊【9月第4期 2025-09-28】
  • 一级a做爰片365网站天门建设局官方网站
  • 电子商城网站制作广东网站营销seo费用
  • HarmonyOS应用开发 - 无受限权限保存资源到媒体库
  • 网上书店电子商务网站建设企业网站模板下载psd格式
  • 京东手机项目:手机受欢迎的影响因素分析
  • linux zgrep命令介绍
  • 成都著名网站建设公司php 抓取 wordpress 文字内容
  • 高性能Go协程库ants实战指南(二)
  • [Android] 【最新更新】电子书/小说下载APP 遇见云书V3.2.0
  • golang面经——map模块和sync.Map模块
  • 【Pandas】pandas Index objects DatetimeIndex.dayofyear
  • 10BASE-T1S存在问题,还不能胜过CAN
  • 网站后台seo设置网站建设的安全性
  • 手机网站制作代理搜索引擎及门户网站介绍总结
  • MySQL、Nignx和Docker在Linux上的安装详解
  • Rust中的特征Trait
  • 《SaaS应用技术攻坚:从定制化到运维的六大核心实践拆解》
  • java-JDK8 日期时间类
  • 网站开发前途电影网站建设基本流程
  • 建网站怎么年赚网页设计网站页面搜索的代码
  • Echarts单轴坐标系散点图
  • t检验(t-test):统计学中的显著性检验方法
  • 音乐网站系统
  • Day17_最小文件系统
  • 参数迁移对迭代次数的影响