get access to functions of a derived class

Hi Friends,
I have a big problem with searching a solution for getting access on getters and setters of the derived classes of an interface.

Interface:
1
2
3
4
5
class IfParam
{
public:
    IfParam();
};


Now I have a derived class for each needed datatype. E.g.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Int32Param: public IfParam
{
public:
    Int32Param();
    Int32Param(IfParam* l_param);
    int getValue();
    void setValue(int l_value);
private:
    int value;
};

class StringParam: public IfParam
{
public:
    Int32Param();
    Int32Param(IfParam* l_param);
    const std::string& getValue();
    void setValue(const std::string& l_value);
private:
    std::string value;
};

My Problem now ist getting access to the getters/setters over the interface.
I wish I could initialize the Params like this:
1
2
3
4
5
IfParam* param = new Int32Param();
param.setValue(12);

IfParam* param = new StringParam();
param.setValue("String");

But to have access to the getter/setter I have to declaire the functions in the interface as generic functions. But how?
I tried to use temlates, but then i have to declaire IfParam as IfParam<int>. Thats a problem because in my original program I do not know which TypeParam the IfParam interface will be initialized with when I create the pointer.

Sorry for my bad english, I am german^^
Thank you very much
Best Regards
Marcel
You can use overloaded virtual functions.

Base class:
1
2
    virtual void setValue(const std::string &l_value);
    virtual void setValue(int l_value);


Derived class (Int32Param)
 
    virtual void setValue(int l_value) override;


Derived class StringParam
 
    virtual void setValue(const std::string &l_value) override;


Also:
 
    IfParam* param = new Int32Param(); // Java style 


Can be written as:
 
    IfParam* param = new Int32Param; // Automatically calls ctor as well... 
Last edited on
you might use dynamic_cast like so:

1
2
3
4
5
6
7
8
9
IfParam* param = ...

Int32Param* i_param = dynamic_cast<Int32Param *>(param);
if(i_param)
  i_param->setValue(12);

StringParam *s_param = dynamic_cast<StringParam *>(param);
if(s_param)
  s_param->setValue("String");


This way you can check whether it's the right type or not
Last edited on
Okay thank you both.
I read that the use of the dynamic_cast is not really elegant.

@kefin
I didn't know that virtual functions can be overriden either.
But now i have another problem: When I create my virtual functions in the Interface:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class IfParam
{

public:
    IfParam();

    virtual const std::string& getValue() =0;
    virtual void setValue(const std::string& l_value) =0;
    virtual const int& getValue() =0;
    virtual void setValue(const int& l_value) =0;
    virtual const double& getValue() =0;
    virtual void setValue(const double& l_value) =0;
    virtual const time_t& getValue() =0;
    virtual void setValue(const time_t& l_value) =0;
};

The compiler tries to override for example the function
virtual const std::string& getValue() =0;
with
virtual const int& getValue() =0;

This leads to a compiler error.
1
2
/home/marcel/Programming/Qt/dataStream/Parameter/../if_param.h:25:24: error: ‘virtual const int& IfParam::getValue()’ cannot be overloaded
/home/marcel/Programming/Qt/dataStream/Parameter/../if_param.h:23:32: error: with ‘virtual const string& IfParam::getValue()’


Why is that happen and how can I deny it?

Well you're trying to overload the return type. However, overloading works only for arguments. You could try specifying dummy arguments. Another thing is to simply name the functions differently:

1
2
getStringValue()
getIntValue()


In fact, this is what the wxWidgets library seems to use for wxEvents, and it works alright.
I read that the use of the dynamic_cast is not really elegant.
The opposite is true

Are you aware if you write it like that
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class IfParam
{

public:
    IfParam();

    virtual const std::string& getValue() =0;
    virtual void setValue(const std::string& l_value) =0;
    virtual const int& getValue() =0;
    virtual void setValue(const int& l_value) =0;
    virtual const double& getValue() =0;
    virtual void setValue(const double& l_value) =0;
    virtual const time_t& getValue() =0;
    virtual void setValue(const time_t& l_value) =0;
};


you need to overwrite each function in a derived class like StringParam. Whether you want it or not.
you cannot return a local variable in your getValue().
if you want to add another type you need to implement it in the base class and all derived class too.
you probably need an [unnecessary] type variable.
all a kinds of trouble are waiting for you maintaining the mess.


with dynamic_cast you can concentrate on what you really want in your base/derived class without any mess.
if you want something from the derived class it is not a problem
Okay cool thank you all for your answers.
Now I have another problem with the factory template function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    template <typename T>
    inline void createParam(const T& l_value, IfParam*& l_tempParam)
    {
        //if(*l_tempParam)    delete *l_tempParam;
        if(typeid(l_value).name() == typeid(int).name())
        {
            l_tempParam = new Int32Param();
            dynamic_cast<Int32Param*>(l_tempParam)->setValue(l_value);
            return;
        }
        else if(typeid(l_value).name() == typeid(double).name())
        {
            l_tempParam = new DoubleParam();
            dynamic_cast<DoubleParam*>(l_tempParam)->setValue(l_value);
            return;
        }
        else if(typeid(l_value).name() == typeid(std::string).name())
        {
            l_tempParam = new StringParam();
            dynamic_cast<StringParam*>(l_tempParam)->setValue(l_value);
            return;
        }
        else if(typeid(l_value).name() == typeid(time_t).name())
        {
            l_tempParam = new TimeParam();
            dynamic_cast<TimeParam*>(l_tempParam)->setValue(l_value);
            return;
        }

when I give an integer to these function this error occurs in the ifblock of the std::string:
 
invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]


How can that be? It do not even get to this point.

How can that be? It do not even get to this point.
you're mixing runtime and compiletime problems.

If you want to create an specific object depending on the compiletime parameter, do it like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
    inline IfParam*createParam(const int l_value)
    {
            Int32Param *l_tempParam = new Int32Param();
            l_tempParam->setValue(l_value);
            return l_tempParam;
        }
   inline IfParam*createParam(const double l_value)
        {
            DoubleParam *l_tempParam = new DoubleParam();
            l_tempParam->setValue(l_value);
            return l_tempParam;
        }
...

if you make appropriate constructors you don't need to call setValue
Topic archived. No new replies allowed.