开发者

C++ Different constant member in each derived class, how to move function to remove duplication in access?

I have derived classes that differ in some constant attribute. In all derived classes, I have a function that returns attribute. Is there a way to move the get_x function into the base class to remove the duplication? I hav开发者_JAVA百科e looked in this thread and a lot of google searches but I couldn't find exactly what I want: C++ : Initializing base class constant static variable with different value in derived class?

class Derived1: public Base{
    static const attribute x = SOME_ATTRIBUTE1;
    attribute get_x(){
        return x;
    }
};

class Derived2: public Base{
    static const attribute x = SOME_ATTRIBUTE2;
    attribute get_x(){
        return x;
    }
};

I would hope that it would look something like this, but this doesn't work because x isn't defined in base. I've also tried extern, static const attribute x, etc.

class Derived1: public Base{
    static const attribute x = SOME_ATTRIBUTE1;
};

class Derived2: public Base{
    static const attribute x = SOME_ATTRIBUTE2;
};

class Base{
    attribute get_x(){
        return x;
    }
};

Thanks.


A bit kludgy, but you could potentially use something similar to the following to do this:

template <attribute x> class Base
{
    public:
        attribute get_x ( ) { return x; }
};

class Derived1 : public Base<SOME_ATTRIBUTE_1>
{
    ...
};

class Derived2 : public Base<SOME_ATTRIBUTE_2>
{
    ...
};

Similar to Karl's answer, but preserves the inherited/derived relationship (well, almost - see @visitor's comment below).

On the other hand, is there a reason for not doing simple overriding? Eg:

class Base
{
    public:
        virtual attribute get_x ( ) = 0;
};

class Derived1 : public Base
{
    public:
        attribute get_x ( ) { return SOME_ATTRIBUTE_1; };
};

class Derived2 : public Base
{
    public:
        attribute get_x ( ) { return SOME_ATTRIBUTE_2; };
};

EDIT: note that the template approach can be extended to as many attributes as are required, as follows:

template <attribute1 x, attribute2 y ...> class Base
{
    public:
        attribute get_x ( ) { return x; }
        attribute get_y ( ) { return y; }
        ...
};

Another solution having each attribute be a property of the class could be as follows:

class Base
{
    public:
        Base (attribute newX) : x(newX) { }
        attribute get_x ( ) { return x; };
    protected:
        const attribute x;
};

class Derived1 : public Base
{
    public:
        Derived1 ( ) : Base(SOME_ATTRIBUTE_1) { }
};

class Derived2 : public Base
{
    public:
        Derived2 ( ) : Base(SOME_ATTRIBUTE_2) { }
};

Here, each Derived has a constant property that is unique to that class. You can of course drop the const if you prefer.


Well, depending on what the rest of the class looks like, it might be a good use case for a template instead of polymorphic inheritance:

template <attribute X>
class Base{
    attribute get_x(){
        return X;
    }
}

typedef Base<SOME_ATTRIBUTE1> Derived1;
typedef Base<SOME_ATTRIBUTE2> Derived2;


#include <iostream>
#include <typeinfo>

enum attribute {SOME_ATTRIBUTE1, SOME_ATTRIBUTE2};

class Base
{
public:
    virtual attribute get_x() = 0;
};

template <attribute Attr>
class Derived : public Base
{
public:
    virtual attribute get_x() {return Attr;}
};

typedef Derived<SOME_ATTRIBUTE1> Derived1;
typedef Derived<SOME_ATTRIBUTE2> Derived2;

int main()
{
    std::cout << typeid(Derived1().get_x()).name() << '\n';
    return 0;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜