[C ++值语义,不可移植性和继承

问题描述 投票:0回答:1

Shared pointer to an immutable type has value semantics

我正在尝试创建一个具有价值语义的生成器类,看起来像这样

class Pipeline {
public:
  static Pipeline(
     const std::string& name, 
     std::optional<size_t> limitIn,
     std::optional<size_t> limitOut) {...}

  shared_ptr<const Pipeline> limitInput(size limit) const { 
    return make_shared<Pipeline>(name_, size_, limit, limitOut_) ;
  }

  shared_ptr<const Pipeline> limitOutput(size limit) const { 
    return make_shared<Pipeline>(name_, size_, limitInput_, limit) ;
  }
private:
  const string name_;
  const size_t limitInput_;
  const size_t limitOutput_;
};

因为成员变量是const,所以shared_ptr本质上是不可变的。

但是,当我需要添加继承时,此模式会崩溃。对于前:


class Pipeline {
 ...

 virtual void doSomething() const = 0;
}

现在,在任何方法(例如limitOutput中)中,当我需要创建管道的新实例时,我也需要了解派生类,因为我无法再创建管道的实例了。我可以想到的一种解决方法是添加另一个虚拟方法来初始化对象。

class Pipeline {
 ...

 virtual shared_ptr<Pipeline> create(const std::string& name, 
     std::optional<size_t> limitIn,
     std::optional<size_t> limitOut) const = 0;
}

class SpecialPipeline  : public Pipeline {
 ...

 virtual shared_ptr<Pipeline> create(const std::string& name, 
     std::optional<size_t> limitIn,
     std::optional<size_t> limitOut) const override {
    return make_shared<SpecialPipeline>(name, limitIn, limitOut);
 }
};

现在所有方法都将遵循此方法

  shared_ptr<const Pipeline> limitInput(size limit) const { 
    return create(name_, size_, limit, limitOut_);
  }

虽然此方法行之有效,但我个人觉得它并不雅致,涉及重复构造并且不习惯。如何实施呢?任何反馈将不胜感激。

c++ inheritance immutability semantics
1个回答
0
投票

解决此问题的最简单方法是:

  • 不公开构造函数;保护它。
  • 为返回std::unique_ptr<const T>std::shared_ptr<const T>的基本类型和派生类型提供工厂成员。
  • 删除数据成员上的const资格。
  • 添加一个虚拟克隆方法,该方法将进行复制并返回std::unique_ptr<Pipeline>

从外部,由于构造函数不是公共的,因此无法获取非const对象,因此成员不必是const。

由于成员不是const,所以您的突变工厂方法可以:

  • 调用克隆方法进行复制。
  • 更改副本上的数据成员。
  • std::unique_ptr中提取指针,并返回一个带有const目标的新智能指针。

旁注:我不确定为什么示例代码中的Pipeline构造函数会被声明为static; C ++没有静态构造函数,因此不会编译。

© www.soinside.com 2019 - 2024. All rights reserved.