0

I have two derived classes as follows. This is the simplified design version that I have right now.

class A objects are copy-able but they are big. That is why I used reference in the constructor of the derived_1 class.

I used shared_ptr for the class derived_2 in order to make usage of p_a optional. I noticed that I can also use std::optional in the constructor of the class derived_2. By this I can give hint to the user that this argument is indeed optional.

Please take into consideration that this the simplified version and this member p_a is used in all three classes intensively. Also std::shared_ptr<A&> a is not the only argument for the constructor in the real example. I will be thankful if you show me how to use std::optional properly here.

Is it ok to mix std::optional with std::shared_ptr?

class A
{
  int m_a;
public:
  A(int a) :m_a(a) {};
};


class Base
{
protected:
  std::shared_ptr<A> p_a;  //Do I need to change type of p_a???
public:
  Base() {};

  void print()
  {
    if (p_a)
      std::cout << "p_a is allocated\n";
  }
  void virtual check() = 0;
};


class derived_1 : public Base
{
public:
  derived_1(const A& a)
  {
    p_a = std::make_shared<A>(a);
  }
  void check() {};
};

class derived_2 : public Base
  {
  public:
    derived_2(std::shared_ptr<A&> a) //can I use std::optional instead??
      {
      if (a)
        p_a = a;
      }
    void check() {};
  };
H'H
  • 1,638
  • 1
  • 15
  • 39
  • Does it need to be a pointer? Or are you just trying to model 'might exist, might not'? If the latter, then yes, use `optional`, and pass by value/move to the base class. If prior to C++17 or really needing a pointer, use `unique_ptr` unless there is actually to be any real sharing. – underscore_d Jun 16 '20 at 11:21
  • Another question: What on earth is a `shared_ptr` containing a reference meant to do? Does that even work? It shouldn't. Overall, it's not very clear what you're asking wrt the given code. – underscore_d Jun 16 '20 at 11:22
  • @underscore_d Indeed no need to reference, but it works. – H'H Jun 16 '20 at 11:23
  • Does std::optional copy the object? – H'H Jun 16 '20 at 11:27
  • You can `emplace()` directly if assigning a new instance to the `optional`. Or if creating from an existing instance, yes, you would need to copy or move in. Are your mysterious types not copyable/movable? Please edit to clarify in that case. – underscore_d Jun 16 '20 at 11:28
  • I edited question. I can copy class A objects, but since it is big, I would like to avoid it. – H'H Jun 16 '20 at 11:33
  • So you want to keep it by pointer, it seems, not by value. Then pointers already have a 'does not exist' state, and that's `nullptr`. I don't know that `optional` would buy you anything here. Worse, what if someone passes an `optional` that does have a value, but where that value is a `nullptr`? Now you have to check 2 things. Why bother? – underscore_d Jun 16 '20 at 11:36

0 Answers0