Skip to Content
介绍 C++ (Chinese Edition)
book

介绍 C++ (Chinese Edition)

by Frances Buontempo
March 2026
Intermediate
348 pages
3h 59m
Chinese
O'Reilly Media, Inc.
Content preview from 介绍 C++ (Chinese Edition)

第 14 章. 使用 std::variant 和 std::visit

你已经了解如何通过类来实现行为的变体,方法是从一个提供接口的抽象基类开始。 然后,你可以根据需要添加任意数量的派生类,以提供不同的实现。 我用了几章的篇幅,向你介绍了在 C++ 中实现这一目标的所有基础构建块。 虽然需要几个组成部分,但这种方法具有可扩展性:你可以根据需要继续添加额外的派生类型,而无需修改现有代码。

你还可以使用 C++ 的另一项特性——std::variant——来实现行为的变体。 std::variant是 C++17 中引入的一个类模板。 std::variant包含多种备选类型中的一种,C 语言程序员可能会将其视为一种类似于联合体union)的实现方式。 这些类型之间可能完全无关。 这种方法要求在设计之初就确定一组固定的类型,因此其可扩展性不如面向对象编程(OOP)。 不过,std::variant允许您以非侵入式的方式扩展该类型集的行为。 如果您想为类添加功能,可以在基类中添加一个新方法,这将影响所有派生类。 若使用std::variant,则可在不改变包含的类型的情况下提供新功能。 面向对象编程(OOP)便于添加新类型,但难以添加新操作。 变体(Variants)则便于添加新操作,但难以添加新类型,因此 OOP 和变体各有取舍。

本章将向您展示如何使用std::variant在您的交易游戏中添加潜在的奖金或罚金:例如利息支付。 您还将了解到另外两个特性:std::optionalstd::any,它们同样支持多种类型,但设计目标各不相同。

创建和使用 std::variant

让我们为您的交易游戏增添一些额外可能性。 您可以设置一条新闻标题,其类型可以是std::string,并创建其他类型来表示罚款、赠礼或利息支付 您将编写一个新函数,该函数有时会随机返回其中一种类型。 游戏将报告事件是否发生,要么显示该std::string,要么显示一条消息并相应调整资金。

如何返回多种互不相关的类型之一? 如果你有一个基类,可以返回该类的智能指针,多态行为会自动处理相关事宜。 对于互不相关的类型,这种方法行不通。 不过,你可以将任何类型放入std::variant 中。

让我们先在新的events.h文件中定义一些用于罚款、礼物或利息支付的新类型。 由于你希望事件仅偶尔发生,因此也可以定义一个 nonevent。 然后,你可以在std::variant 中使用这些事件和 nonevent:

#include <iostream>
#include <string>
#include <variant>

namespace stock_prices
{
    struct Nothing 1
    {
    };

    struct FixedFine 2
    {
        double fine{};
    };

    struct Gift 
    {
        double gift{};
    };

    struct InterestPayment 
    {
        double percent{};
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.

Read now

Unlock full access

More than 5,000 organizations count on O’Reilly

AirBnbBlueOriginElectronic ArtsHomeDepotNasdaqRakutenTata Consultancy Services

QuotationMarkO’Reilly covers everything we've got, with content to help us build a world-class technology community, upgrade the capabilities and competencies of our teams, and improve overall team performance as well as their engagement.
Julian F.
Head of Cybersecurity
QuotationMarkI wanted to learn C and C++, but it didn't click for me until I picked up an O'Reilly book. When I went on the O’Reilly platform, I was astonished to find all the books there, plus live events and sandboxes so you could play around with the technology.
Addison B.
Field Engineer
QuotationMarkI’ve been on the O’Reilly platform for more than eight years. I use a couple of learning platforms, but I'm on O'Reilly more than anybody else. When you're there, you start learning. I'm never disappointed.
Amir M.
Data Platform Tech Lead
QuotationMarkI'm always learning. So when I got on to O'Reilly, I was like a kid in a candy store. There are playlists. There are answers. There's on-demand training. It's worth its weight in gold, in terms of what it allows me to do.
Mark W.
Embedded Software Engineer

You might also like

Navigating the midcareer plateau

Navigating the midcareer plateau

Uma Chingunde
Run Llama-2 Models

Run Llama-2 Models

Federico Castanedo

Publisher Resources

ISBN: 0642572352684