Shared pointer to an immutable type has value semantics
I am trying to create a builder class which has value semantics which looks like something like this
class Pipeline {
public:
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_;
};
Since member variables are const, shared_ptr is essentially immutable.
However this pattern breaks down when I need to add inheritance. For ex:
class Pipeline {
...
virtual void doSomething() const = 0;
}
Now in any of the methods (say in limitOutput) when I need to create a new instance of Pipeline I would need to know about the derived class as well since I cannot create an instance of Pipeline anymore. One way I can think of to solve this is to add another virtual method to initialize the object.
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);
}
};
Now all methods would just defer to this
shared_ptr<const Pipeline> limitInput(size limit) const {
return create(name_, size_, limit, limitOut_);
}
While this works I personally feel it isn't elegant, involves duplication construction and doesn't feel idiomatic. How would one go about implementing this ? Any feedback would be appreciated.