C ++ Различный константный член в каждом производном классе, как переместить функцию для удаления дублирования в доступе? - PullRequest
3 голосов
/ 23 февраля 2011

У меня есть производные классы, которые отличаются некоторым постоянным атрибутом. Во всех производных классах у меня есть функция, которая возвращает атрибут. Есть ли способ переместить функцию get_x в базовый класс, чтобы удалить дублирование? Я посмотрел в этой теме и много поисков Google, но я не мог найти именно то, что я хочу: C ++: Инициализация постоянной статической переменной базового класса с другим значением в производном классе?

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;
    }
};

Я надеюсь, что это будет выглядеть примерно так, но это не работает, потому что x не определен в базе. Я также пробовал extern, статический атрибут const x и т. Д.

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;
    }
};

Спасибо.

Ответы [ 3 ]

2 голосов
/ 23 февраля 2011

Немного неаккуратно, но вы могли бы потенциально использовать что-то похожее на следующее, чтобы сделать это:

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>
{
    ...
};

Аналогично ответу Карла, но сохраняет унаследованное / производное отношение (ну, почти - см. @ Visitor'sкомментарий ниже).

С другой стороны, есть ли причина не делать простое переопределение?Например:

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; };
};

РЕДАКТИРОВАТЬ: обратите внимание, что шаблонный подход может быть расширен на столько атрибутов, сколько требуется, как указано ниже:

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

Другое решение, имеющееКаждый атрибут, являющийся свойством класса, может быть следующим:

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) { }
};

Здесь каждый Derived имеет свойство константы, уникальное для этого класса.Вы, конечно, можете отказаться от const, если хотите.

1 голос
/ 23 февраля 2011
#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;
}
1 голос
/ 23 февраля 2011

Ну, в зависимости от того, как выглядит остальная часть класса, это может быть хорошим вариантом использования шаблона вместо полиморфного наследования:

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

typedef Base<SOME_ATTRIBUTE1> Derived1;
typedef Base<SOME_ATTRIBUTE2> Derived2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...