【问题标题】:How to display underlying data in a type erasure class using shared_ptr如何使用 shared_ptr 在类型擦除类中显示底层数据
【发布时间】:2018-12-26 19:10:48
【问题描述】:

好的,所以我有一个非常简单的类,它使用类型擦除,使用共享指针。

class Prop
{
    struct PropConcept
    {
        virtual ~PropConcept() {}
    };
    template<typename T>
    struct PropModel : PropConcept
    {
        PropModel(const T& t) : prop(t) { }
        PropModel() {}
        virtual ~PropModel() {}
    private:
        T prop;
    };

    std::shared_ptr<PropConcept> prop;
public:

    template<typename T>
    Prop(const T& obj) : prop(new PropModel<T>(obj)) { }
    Prop() {};
};

这里没有问题,但是由于它的工作方式,调试器显示了从 Prop 到 std::shared_ptr(PropContent) 再到 PropModel 的完整链,最后是包含实际数据的底层模板化 prop。

我想做的是编写一个 natvis 规则来显示底层数据,而不是整个链。不幸的是,我得到的最远的是取消引用指针,这让我只剩下它指向的 PropConcept 结构。

<Type Name="Prop">
   <DisplayString>{*prop}</DisplayString>
   <Expand>
      <Item Name="prop">(*prop)</Item>
   </Expand>
</Type>

当然,我的问题是,如何遍历“树”以到达 PropModel 结构的“prop”成员?类本身是否需要调整,或者它是否只是纯 natvis 都没关系——只要类型擦除仍然存在,我不必扩展 4 个项目来获取数据。

提前感谢您的帮助。

【问题讨论】:

    标签: c++ shared-ptr natvis


    【解决方案1】:

    就像为Prop::PropModel添加逻辑一样简单:

    <Type Name="Prop::PropModel&lt;*&gt;">
      <DisplayString>{prop}</DisplayString>
      <Expand>
        <Item Name="prop">prop</Item>
      </Expand>
    </Type>
    

    我已经测试过

    Prop p1{};
    Prop p2{ 42 };
    Prop p3{ std::string{"x"} };
    

    显示是

    如您所见,Prop 类型的代码不是最佳的。它可以检查空的shared_ptr 并为此提供额外的显示。如果您希望某些类型以不同方式显示,例如 ints 以十进制显示,我对 Prop::PropModel 的逻辑也可以改进。

    顺便说一句,您应该启用 MSVC 代码分析。您的代码触发了一些警告。

    【讨论】:

    • 谢谢!在几天没有回答之后,我又玩了一点,并且在接近这个答案时感到害怕 - 只是忽略了 PropModel 扩展标签。另外,感谢您的建议 - 在此代码离开我的计算机之前,我一定会检查代码分析。我同意,我应该处理一个空指针,但如果它曾经是,那表明一个更大的问题。所以至少现在,默认值就可以了。我会将我的最终结果作为答案,但将您的结果标记为正确。
    【解决方案2】:

    我最终更接近 Werner Henze 的答案,但说答案提供了我需要的最终信息。为了完整起见,下面是我对这个类的最终 natvis,以及它在调试器中的显示方式。在这种情况下,shared_ptr 指向一个std::vector&lt;int&gt;

      <Type Name="Prop">
        <DisplayString>{*prop}</DisplayString>
        <Expand>
          <ExpandedItem>(*prop)</ExpandedItem>
        </Expand>
      </Type>
    
      <Type Name="Prop::PropModel&lt;*&gt;">
        <DisplayString>{prop}</DisplayString>
        <Expand>
          <ExpandedItem>prop</ExpandedItem>
        </Expand>
      </Type>
    

    这会导致...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-05
      • 2018-06-18
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      相关资源
      最近更新 更多