比较 std::unique_ptr 指向的底层(派生)类型

Posted

技术标签:

【中文标题】比较 std::unique_ptr 指向的底层(派生)类型【英文标题】:Comparing underlying (derived) types pointed-to by std::unique_ptr 【发布时间】:2020-10-04 18:22:52 【问题描述】:

我正在编写单元测试来练习涉及工厂类的各种代码路径。

工厂将std::unique_ptr 返回到基本类型:

class Base ;
class Derived1 : public class Base ;
class Derived2 : public class Base ;

std::unique_ptr<Base> Type::Factory(enum rtype) const 
    switch(rtype) 
        case d1: return std::make_unique<Derived1>();
        case d2: return std::make_unique<Derived2>();
        default: return std::make_unique<Derived1>();
    

所以在测试中我要确保返回正确的类型(工厂是剪切粘贴错误的温床)。

有没有办法检查返回的类型? 这:EXPECT_TRUE(typeid(Derived1), typeid(type.get()); 是错误的,因为 type.get()Base 而不是传入的 rtype

【问题讨论】:

我希望如果你这样做 typeid(*type.get()) 那么它会检查动态类型,不是吗? 这能回答你的问题吗? Get object's type from pointer to base class at runtime 第二个答案说按照我的建议取消引用指针。 default 返回Derived1 看起来很可怕。 @underscore_d 这行得通。我正在搜索“比较底层类型”,但它没有五个链接。 【参考方案1】:

您需要使用 RTTI。使用时类型被擦除为Base

您可以进行动态转换以获得正确的类型,例如:

EXPECT_FALSE(dynamic_cast<Derived1*>(type.get()) == nullptr)

如果 dynamic_cast 失败(类型不是 Derived1)dynamic_cast 将返回 nullptr

【讨论】:

【参考方案2】:

这:EXPECT_TRUE(typeid(Derived1), typeid(type.get());false,因为 type.get()Base,而不是传入的 rtype

typeid( type.get() ) 将获得基指针的typeid,即get() 被声明为返回的类型。要获得指向对象的真正动态类型,无论它是什么,都应该取消对指针的引用:

typeid( *type.get() )

【讨论】:

以上是关于比较 std::unique_ptr 指向的底层(派生)类型的主要内容,如果未能解决你的问题,请参考以下文章

std::unique_ptr 不是零成本

使用 std::unique_ptr.reset() 更改指针下的对象

智能指针用法

如何调用指向函数指针的指针?

深入了解C++ (15) | 源码分析auto_ptr & unique_ptr 设计

指向基类的指针的 std::vector 的深拷贝