Implementing complex inheritance in C ++

I have the following existing classes:

class Gaussian {
public:
  virtual Vector get_mean() = 0;
  virtual Matrix get_covariance() = 0;
  virtual double calculate_likelihood(Vector &data) = 0;
};

class Diagonal_Gaussian : public Gaussian {
public:
  virtual Vector get_mean();
  virtual Matrix get_covariance();
  virtual double calculate_likelihood(Vector &data);
private:
  Vector m_mean;
  Vector m_covariance;
};

class FullCov_Gaussian : public Gaussian {
public:
  virtual Vector get_mean();
  virtual Matrix get_covariance();
  virtual double calculate_likelihood(Vector &data);
private:
  Vector m_mean;
  Matrix m_covariance;
};

As you can see, the Gaussian class acts as an interface, but has no implementation. It all works fine.

Now I want to create the "AdaptedGaussian" class, where the data vector provided to the calculated likelihood will be changed before the probability is calculated.

Some requirements:

  • AdaptedGaussian must be a child of the Gaussian class
  • AdaptedGaussian should be able to "wrap" or "be an instance" of all possible Gaussian classes
  • AdaptedGaussian must be built from an existing Gaussian object

Now I have an idea:

class Adapted_Gaussian : public Gaussian {
private:
  Gaussian* m_g;

public:
  virtual Vector get_mean() { return m_g->get_mean(); }
  virtual Matrix get_covariance() { return m_g->get_covariance(); }
  virtual double calculate_likelihood(Vector &data) 
  { 
    //do something with data
    return g->calculate_likelihood(Vector &data); 
  }
} 

There may be some disadvantages:

  • For each method (and here more than shown here) in the new class
  • ,
  • - , , .

? ?

m_g?

+3
4

, , . Gaussian. .

  • Java -, . , , , .
  • Gaussian- , , .
+5

, . , ( ) . , - AdaptedGaussian , , .

template<class BaseGaussian> class AdaptedGaussian : public BaseGaussian
{
    virtual double calculate_likelihood(Vector &data) 
    { 
        // do something with data
        return BaseGaussian::calculate_likelihood(Vector &data); 
    }
};

.

AdaptedGaussian XXXGaussian, , XXXGaussian , :

template<class BaseGaussian> class AdaptedGaussian : public BaseGaussian
{
public:
    AdaptedGaussian(const BaseGaussian& other) : BaseGaussian(other)
    {
    }
    // ...
};
+2

, Strategy Pattern.

, "". , , . . ( ).

: ( )

class Gaussian {
   private:
      Cl_Strategy* m_cl_strategy;

   public:
      Gaussian(Cl_Strategy* cl_strategy) {
         m_cl_strategy = cl_strategy;
      };
      virtual Vector get_mean() = 0;
      virtual Matrix get_covariance() = 0;
      virtual double _calc_likelihood(Vector &data) = 0;
      virtual double calculate_likelihood(Vector &data) {
         m_cl_strategy->do_your_worst(this, data);
         return _calc_likelihood(data);
      };
};

, , ++ ...

_calc_likelihood , calculate_likelihood .

, , .

+1

Java typically uses both an interface and an abstract class that implements it to provide default behavior for all methods. (See the Joshua Bloch collection API design in the java.util package.) Perhaps this can help you here as well. You will give customers the choice of using an interface or abstract class.

You can also try the composition . Pass an instance of adapted Gaussian to subclasses and defer its behavior.

0
source

Source: https://habr.com/ru/post/1711064/


All Articles