Reputation: 96
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
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