Hulk
Hulk

Reputation: 96

How to return the member of template derived class from base?

Is it possible to return a template member of a derived class by the base?

Please find the following classes:

Data.h:

#include <string>

class IData{
public:
    virtual ~IData(){};
    virtual const std::string& getName() const = 0;
};

template <typename T>
class DataImpl: public IData
{
public:
    DataImpl(const std::string& name, T* ptrToData)
            :_name(name)
            ,_ptrToData(ptrToData)
        {};
    ~DataImpl(){};

  const std::string& getName() const
  {
    return _name;
  }

  const T* getDataPtr() const
  {
    return _ptrToData;
  }

private:
    std::string         _name;

    T*                  _ptrToData; // <-- how to return this pointer ?
};

Component.h:

#include <vector>
#include <string>
#include "Data.h"

class Component
{
public:
    Component(const std::string& name)
    :_name(name)
  {};

  ~Component(){};

  const std::string& getName() const
  {
    return _name;
  };

  std::vector<IData*>& getDataList()
  {
    return _dataList;
  };

  void addData(IData* ptr)
  {
    _dataList.push_back(ptr);
  };

private:
    std::string             _name;
    std::vector<IData*>     _dataList;
};

main.cpp:

#include <iostream>
#include <vector>
#include <string>

#include "Component.h"
#include "Data.h"

int main()
{
  // primitive types
  int x = 5;
  float y = 5.7;
  bool b = false;

  // complex structures
  struct complex{
    int a;
    std::string c;
  };

  complex cx;
  cx.a = 5;
  cx.c = "anything";

  DataImpl<int> d1("x", &x);
  DataImpl<float> d2("y", &y);
  DataImpl<bool> d3("b", &b);
  DataImpl<complex> d4("complex", &cx);

  Component cmp("cmpName");
  cmp.addData(&d1);
  cmp.addData(&d2);
  cmp.addData(&d3);
  cmp.addData(&d4);


  std::vector<IData*>::iterator it = cmp.getDataList().begin();

  for (;it != cmp.getDataList().end(); ++it)
  {
    IData* ptr = *it;

    std::cout << ptr->getName() << std::endl;

  }

  return 0;
}

Inside the loop in the main.cpp, I was accessing every DataImpl member. But I want to return/get the member variable T* _ptrToData through the base class IData but so far I did not find any way.

I have a compiler restriction to c++98

Thanks in advance.

Upvotes: 1

Views: 103

Answers (1)

Jeune Prime Origines
Jeune Prime Origines

Reputation: 239

You can try to use dynamic_cast to perform a type-safe downcast of the IData* pointer back to the pointer of the derived class (e.g. DataImpl<int>* ) . However, this may require the Run-time type information (RTTI) of the compiler enabled.

Here's an example:

  for (;it != cmp.getDataList().end(); ++it)
  {
    IData* ptr = *it;

    std::cout << ptr->getName() << std::endl;

    DataImpl<int>* pInt = dynamic_cast<DataImpl<int>*>(ptr);
    if (pInt) {
        std::cout << "*pInt->getDataPtr(): " << *pInt->getDataPtr() << std::endl;
        std::cout << "pInt->getDataPtr(): "  << pInt->getDataPtr() << std::endl;
    }

    DataImpl<float>* pfloat = dynamic_cast<DataImpl<float>*>(ptr);
    if (pfloat) {
        std::cout << "*pfloat->getDataPtr(): " << *pfloat->getDataPtr() << std::endl;
        std::cout << "pfloat->getDataPtr(): "  << pfloat->getDataPtr() << std::endl;
    }

    DataImpl<bool>* pbool = dynamic_cast<DataImpl<bool>*>(ptr);
    if (pbool) {
        std::cout << "*pbool->getDataPtr(): " << *pbool->getDataPtr() << std::endl;
        std::cout << "pbool->getDataPtr(): "  << pbool->getDataPtr() << std::endl;
    }

  }

Upvotes: 1

Related Questions