【问题标题】:Pure virtual method that returns children of an abstract class?返回抽象类的子级的纯虚方法?
【发布时间】:2018-03-20 21:12:38
【问题描述】:

我正在尝试创建一个抽象类,其子类必须重写的方法之一应该返回子类的实例。

class JsonSerializable {
public:
    virtual <child_of_JsonSerializable> fromJson(string jsonStr) const = 0;
};

class ConcreteSerializable : public JsonSerializable {
public:
    ConcreteSerializable fromJson(string jsonStr) const {
        return ConcreteSerializable();
    }
};

我尝试使用 answer 之后的模板,但收到 templates may not be virtual 的错误。

有没有办法在不使用原始指针作为返回类型的情况下做我正在寻找的事情?

【问题讨论】:

  • 你看过CRTP吗?
  • 看起来你正在寻找的是一个伪装成成员函数的工厂方法。返回基类有什么问题?所有虚函数仍将按预期运行,唯一的问题是sizeof,这意味着您需要小心将它们存储在数组中或通过memcpy 进行复制——这两者在还是第一名
  • @YePhIcK CRTP 似乎是我的问题的解决方案,但我想明白你的意思。如何返回基类?基类是抽象的,如果我把它作为返回类型,我会得到一个编译错误。
  • struct Derived: Base { Base&amp; get() {return *this;} }; 是一种方法

标签: c++ c++17


【解决方案1】:

您不能创建抽象类型的对象。而且因为你不能创建这样的对象,你也不能返回它。这就是为什么所有返回基类/派生对象的示例总是返回一个指针或一些对基类的引用的原因

struct B {
    virtual B *fromJson(const std::string &jsonStr) const = 0;
};

struct D : public B {
    D(const std::string &jsonStr);
    D *fromJson(const std::string &jsonStr) const;
};

D *D::fromJson(const std::string &jsonStr) const
{
    return new D(jsonStr);
}

【讨论】:

  • 是的,我知道。我希望我可以用智能指针或模板做一些技巧。 CRTP 似乎是解决我的问题的好方法,所以我会继续这样做。
【解决方案2】:

您是否尝试实现以前使用 CRTP 完成的某些事情?

struct Interface {
    virtual Interface *inflate(std::string const &json) = 0;
    virtual ~Interface() {}
};

template<typename Child> struct Base: public Interface {
    Interface *inflate(std::string const &json) { return new Child(json); }
};

struct Child: public Base<Child> {
    Child(std::string const &json);
};

【讨论】:

  • 你是在用问题回答问题吗? ;-)
  • 你为什么好奇? :D
  • 那是你想让我微笑的意图吗?
  • 你真的应该在这里提供Child的构造函数的主体,否则很不清楚发生了什么
  • 嗯...如果我能。给inflateFromJson(json); 一个电话就够了吗?
猜你喜欢
  • 2012-10-01
  • 2010-12-13
  • 2014-04-03
  • 2010-11-22
  • 1970-01-01
  • 2016-12-28
  • 2020-11-19
  • 1970-01-01
  • 2019-01-01
相关资源
最近更新 更多