【问题标题】:Reusable member function in C++C++中可重用的成员函数
【发布时间】:2020-07-16 10:16:58
【问题描述】:

我正在使用这个成员函数来获取指向对象的指针:

    virtual Object* Create()
    {
        return new Object();
    }

它是虚拟的,所以我可以获得指向派生对象的指针,现在我这样做:

    virtual Object* Create()
    {
        return new Foo();
    }

它工作正常,但我想做这样的事情来防止任何错误,也让它更容易,所以我不必每次创建新类时都重写该函数:

    virtual Object* Create()
    {
        return new this();
    }

我试图找到如何做到这一点,但找不到任何有用的东西,也许这是不可能的。我正在使用带有 C++17 的 MSVC 编译器

【问题讨论】:

  • 如果我正确理解了您的问题,您希望在基类中 Create 的定义中检索对象的实际(动态)类型。无需覆盖Create。我对吗?如果是这样,我不明白您为什么接受实际上需要覆盖的答案。
  • 无论如何,您基本上是在尝试解决与 clone 模式 中出现的问题相同的问题,而无需覆盖 clone 函数。这可以在 CRTP 的帮助下实现;参见,例如,this article
  • 仅供参考:SO: How to implement ICloneable without inviting future object-slicing(关于某种类似的问题)。
  • @DanielLangr 主要是我需要知道怎么做new this(),覆盖对我来说没什么问题,我只需要防止错误

标签: c++ visual-c++ c++17 typetraits


【解决方案1】:

你可以从this指针中获取类型

virtual Object* Create() override
{
    return new std::remove_pointer_t<decltype(this)>;
}

LIVE

PS:请注意,您仍然需要覆盖每个派生类中的成员函数。根据您的需求,使用CRTP,您只需在基类中实现Create。例如

template <typename Derived>
struct Object {
    Object* Create()
    {
        return new Derived;
    }
    virtual ~Object() {}
};

然后

struct Foo : Object<Foo> {};
struct Bar : Object<Bar> {};

LIVE

【讨论】:

  • 这不起作用,因为 decltype(this) 返回的不是派生类型。它只返回 this 的声明类型,也就是你定义这个方法的类型类。
  • 不,只有一个实现。我认为他希望为每个派生类生成一个实现 - 这可以通过 CRTP Pattern
  • @BerndBaumanns 我明白你的意思。添加到答案中。
  • 如果Object 是一个模板,那么FooBar 没有相同的基类。通常,您有一个(非模板)基础,然后是一些从中派生的模板化中间类来实现 CRTP,例如描述的here
  • @Chris decltype(this) 产生类型Object*std::remove_pointer_t&lt;decltype(this)&gt; 产生类型Object,则return 语句与return new Ojbect; 相同,即返回Object*
猜你喜欢
  • 2021-09-11
  • 1970-01-01
  • 1970-01-01
  • 2016-03-28
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 2021-01-08
相关资源
最近更新 更多