第三节 · 摆脱单亲状态 · 多重继承与虚继承

有时我们需要存储任意类型的值,C++17 提供了 std::any 来实现类型安全的类型擦除。


void 的问题*

// 旧方法:不安全
void* data = new int(42);
int* p = static_cast<int*>(data);  // 必须记住类型
cout << *p << endl;
delete static_cast<int*>(data);

// 如果类型记错了,就是未定义行为
string* s = static_cast<string*>(data);  // 危险!

std::any

#include <any>

int main()
{
    any a = 42;
    cout << any_cast<int>(a) << endl;  // 42
    
    a = string("Hello");
    cout << any_cast<string>(a) << endl;  // Hello
    
    a = 3.14;
    cout << any_cast<double>(a) << endl;  // 3.14
    
    // 类型不匹配会抛出异常
    try
    {
        cout << any_cast<int>(a) << endl;
    }
    catch (const bad_any_cast& e)
    {
        cout << "Bad cast: " << e.what() << endl;
    }
    
    return 0;
}

any 的操作


std::variant

variant 是类型安全的联合体。


访问者模式与 variant


std::optional

表示可能没有值的类型。


手动实现类型擦除


函数包装器 std::function


类型擦除的应用


习题

  • 比较 anyvariantvoid* 的优缺点。

  • 实现一个简单的属性系统,支持任意类型的属性值。

  • 使用 variant 实现一个简单的 JSON 值类型。

Last updated