0
#include "dataConsumer.h"

#include <iostream>
#include <Windows.h>

DataConsumer::DataConsumer(){}
DataConsumer::~DataConsumer(){}

void DataConsumer::Body()
{
    std::cout << "DataConsumer Start" << std::endl;

    while (1)
    {
        //I want to get providerData_ of DataProvide class in here

        Sleep(1000);
    }
}


#include "dataProvider.h"

#include <iostream>
#include <Windows.h>

DataProvider::DataProvider(){}
DataProvider::~DataProvider(){}

void DataProvider::Body()
{
    std::cout << "DataProvider Start" << std::endl;

    while (1)
    {
        //Update data in here
        providerData_++;

        Sleep(1000);
    }
}

There are two classes. And I want to get providerData_ of dataProvider class in dataConsumer class.

To resolve this situation, I thought the following is one solution. I made singleton dataTransfer class like below. But I am not sure whether this is a general solution in c++. First of all, I want to know whether my solution is available. To the next, If you know the better solution(or design pattern) to resolve my situation, please advise to me.

#ifndef DATATRANSFER_H
#define DATATRANSFER_H

class DataTransfer
{
public:
    static DataTransfer* getInstance()
    {
        static DataTransfer instance;
        return &instance;
    }
    void GetData(unsigned int *data)
    { 
        if(data)
            *data = data_;
    }
    void SetData(unsigned int *data)
    { 
        if(data)
            data_ = *data;
    }

private:
    DataTransfer(){}
    ~DataTransfer(){}

    unsigned int data_;
};

#endif


#include "dataConsumer.h"
#include "dataTransfer.h"

#include 
#include 

DataConsumer::DataConsumer(){}
DataConsumer::~DataConsumer(){}

void DataConsumer::Body()
{
    unsigned int data = 0;
    std::cout << "DataConsumer Start" << std::endl;

    while (1)
    {
        //I want to get providerData_ of DataProvide class in here
        DataTransfer::getInstance()->GetData(&data);

        std::cout << "DataConsumer data:" << data << std::endl;

        Sleep(1000);
    }
}

#include "dataProvider.h"
#include "dataTransfer.h"

#include 
#include 

DataProvider::DataProvider() : providerData_(0)
{
}

DataProvider::~DataProvider(){}

void DataProvider::Body()
{
    std::cout << "DataProvider Start" << std::endl;

    while (1)
    {
        //Update data in here
        providerData_++;

        DataTransfer::getInstance()->SetData(&providerData_);

        Sleep(1000);
    }
}
Hercoa
  • 49
  • 7

2 Answers2

1

If both classes need to be able to get and set the providerData_, I would create a third Data class to own the providerData_. Then I could give a pointer of the Data class to all the classes that needed access to that data.

skybaks
  • 43
  • 1
  • 5
0

There are 3 patterns called aggregation, composition and association in software architecture.

The pattern in which class Foo can use class Bar but does not "own" it and both classes remain independent is Association.

DataConsumer have a pointer to DataProvider :

// Association 
class DataConsumer{
 private:
  DataProvider* provider;
 public:   
  void setProvider(DataProvider* p) { provider = p; }
  void Body();
  int /* or whatever data type */ getData() 
  {
      if(provider != nullptr) 
      {
          return provider->getData();
      } 
      else 
      {
          // handle provider not being set
          return ...;
      }
  }
};

DataProvider must be allocated / created outside of DataConsumer and is independent.

Read this answer and this answer for a better explanation on these pattern.

adrtam
  • 6,160
  • 2
  • 6
  • 23
Clonk
  • 1,837
  • 1
  • 10
  • 25
  • thanks for your answer, could you let me know that I want to know whether my solution(=dataTransfer singleton class) is available? – Hercoa Mar 14 '19 at 14:40
  • If by available you means "will it work" then yes, your solution will work. But using singleton is not necessary here and on complex program can just complicate things and create more [problems](https://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons?rq=1) . – Clonk Mar 14 '19 at 14:48
  • Keep in mind the single responsability principle. DataProvider (per his name) is here to provide data. In your example, the reponsability of providing datas is unnecessary shared between DataProvider and DataTransfer. Let's say in the future someone want to change the type of datas shared from int to a class MyDataType, you have to change 2 class (with possibly hard to find error if both classes are not changed accordingly). – Clonk Mar 14 '19 at 14:57
  • Thanks for your kind advice. But If I add one restriction condition(=dataConsumer class can not use directly dataProvider class) due to some reason, In this situation, there are other solutions? – Hercoa Mar 14 '19 at 15:30
  • There are infinite ways of writing code that could solve your problem. The question is which one is the best (i.e. less complicated to develop and maintain) solution. It depends on the reason why DataConsumer cannot use DataProvider. If it's because you are using a library you cannot modify, then you can just create a wrapper do whatever you want with it. – Clonk Mar 14 '19 at 15:36