Strategy on how to share parameters between an object and one of its members

I would like to ask what is the "best" way to share a parameter between an object and one of its members. I am trying to explain my problem better: I have a class A that requires a certain parameter:

class A
{
public:
  A(int);
  ~A();
private:
  int ParameterA;
  ...
}

      

Also I have a second class B that contains an object of class A as its member and needs another parameter to be defined:

class B
{
public:
  B(int);
  ~B();
private:
  A  MemberA;
  int ParameterB;
  ...
}

      

Now my question is, if ParameterA and ParameterB are always equal, what is the "best" (clean) strategy to use?

I thought of three possibilities

  • The first option is to have two copies of the same value stored with different names, like in the above code. This seems completely "dangerous" to me, it will force me to always check that these two values ​​are equal.
  • Declare public ParameterA so class B can access it.
  • Define get function so that class B can access ParameterA using get function

Is there any other (better / standard) approach to solve this case? Which method should you follow?

+3


source to share


3 answers


You can declare ParameterA as a reference and program it to reference ParameterB.



class A
{
public:
  A(int& val) : ParameterA(val) {}
  ~A(){}

private:
  int& ParameterA;
};

class B
{
public:
  B(int val) : ParameterB(val), MemberA(ParameterB) {}
 ~B(){}

private:
  int ParameterB;
  A  MemberA;
};

      

+1


source


Your intuition about the dangers of having two variables always having the same meaning is correct: it is at least a code smell and should be avoided.

The straightforward solution is inheritance:



class A {
    public:
        A(int a) : parameterA(a) {}
    protected:
        int parameterA;
};

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

      

Of course, it depends on the context if this solution is appropriate, but it should always be the first to be evaluated.

+1


source


The "best" way is likely to depend on how you use A

and B

.

Of your options, I would avoid 1 and 2 if possible, but I think 3 might be a reasonable option if the parameter is really not what you want to expose. If you want to keep the parameter private, you can make a B

friend A

.

Another option is to transfer ownership of this parameter away from A

. You can define a parameter outside the class (perhaps inside another class) and pass a reference or pointer to B

and A

.

A more flexible approach might be to use a shared pointer, but you may not need this flexibility in practice. By using shared_ptr

, you don't restrict what you can do with your classes like references, and you don't bind the lifetime A

or B

lifetime of an external object. And you can easily create a standalone A

yourself if you like:

#include <memory>

using SharedInt = std::shared_ptr<int>;

class A {
public:
  A(SharedInt parameter) : parameter_(parameter) {}
private:
  SharedInt parameter_;
};

class B {
public:
  B(SharedInt parameter) : a_(parameter), parameter_(parameter) {} 
private:
  A  a_;
  SharedInt parameter_;
};  

int main() {
  auto b = B(std::make_shared<int>(3));
  auto a = A(std::make_shared<int>(7));
}

      

But I might be tempted to go for a more restrictive design first and move on to generic pointers if necessary.

+1


source







All Articles