Search code examples
c++pure-virtual

c++ Using implementation of parent class


Regarding the following code, I would avoid copy paste so much code, or implement the interface class IHardware:

#include <iostream>
#include <string>

class IHardware
{
public:
  virtual ~IHardware() = default;
  virtual uint8_t GetHardwareData() const = 0; // I would to keep it pure virtual to beiong able to mock it
  // I could use: uint8_t GetHardwareData() const { return 50; } and delete Hardware implementation class
};

class ISoftwareA : public IHardware
{
public:
  virtual ~ISoftwareA() = default;
  virtual uint8_t GetSoftwareData() const = 0;
};

class ISoftwareB : public IHardware
{
public:
  virtual ~ISoftwareB() = default;
  virtual std::string GetSoftwareData() const = 0;
};

class Hardware : public IHardware // I want to keep this to let the possibility to change the hardware implementation
{
  uint8_t return_value_ = 50;
public:
  uint8_t GetHardwareData() const override { return return_value_; }
};

class TestA final : public ISoftwareA, public Hardware
{
public:
  uint8_t GetSoftwareData() const override { return 10; };
  uint8_t GetHardwareData() const override { return Hardware::GetHardwareData(); } // <- All TestX class will not override it, and I don't want to copy paste and override in every class
};

class TestB final : public ISoftwareB
{
public:
  std::string GetSoftwareData() const override { return "test"; }
  // Is there a way to use Hardware implementation ??
};

int main()
{
  std::cout << "Hello World!\n";
  TestA test_a;
  TestB test_b;

  std::cout << std::to_string(test_a.GetHardwareData()) << '\n';
  std::cout << std::to_string(test_a.GetSoftwareData()) << '\n';
  std::cout << std::to_string(test_b.GetHardwareData()) << '\n';
  std::cout << test_b.GetSoftwareData() << '\n';
}

I would like to being able to use implementation of parent class (see comment in code). Can TestB class use implementation of Hardware class Is that even possible?


Solution

  • You should be aware of the diamond problem, which requires you to add those overrides unless all classes were modified to virtually inherit IHardware

    class ISoftwareA : public virtual IHardware
    ...
    class ISoftwareB : public virtual IHardware
    ...
    class Hardware : public virtual IHardware
    ...
    
    class TestB final : public ISoftwareB, public Hardware
    {
    public:
      std::string GetSoftwareData() const override { return "test"; }
      // GetHardwareData taken from Hardware
    };
    

    godbolt demo