Проблема C ++: продвижение класса с использованием производного класса - PullRequest
3 голосов
/ 25 июня 2011

У меня есть класс для Float32, который является производным от Float32_base


    class Float32_base {
        public:
        // Constructors
        Float32_base(float x) : value(x) {};
        Float32_base(void) : value(0) {};
        operator float32(void) {return value;};
        Float32_base operator =(float x) {value = x; return *this;};
        Float32_base operator +(float x) const { return value + x;};

    protected:
        float value;

    }

    class Float32 : public Float32_base {
        public:
        float Tad() {
            return value + .01;
        }
    }

    int main() {
        Float32 x, y, z;
        x = 1; y = 2;

    // WILL NOT COMPILE!
        z = (x + y).Tad(); 

    // COMPILES OK
        z = ((Float32)(x + y)).Tad(); 
    }

Проблема в том, что оператор + возвращает Float32_base, а Tad () не принадлежит этому классу. Но «х» и «у» - это Float32.

Есть ли способ получить код для компиляции в первой строке, не прибегая к преобразованию типов, как я делал в следующей строке?

Ответы [ 3 ]

2 голосов
/ 25 июня 2011

Вы можете использовать CRTP , если вам нужно только одноуровневое глубокое наследование:

template <typename T>
struct A
{
  T
  operator+ (const A&)
  { return T (); }
};

struct B : A <B>
{
  void
  lol ()
  { }
};

int
main ()
{
  B a, b;
  (a + b).lol ();
}
0 голосов
/ 25 июня 2011

Вы можете шаблонизировать класс FLoat32_base по типу результата операций.

Или поместить все в один класс (вероятно, лучший), делегируя несколько операций, специфичных для платформы, функциям, специфичным для платформы.

Ура & hth.,

0 голосов
/ 25 июня 2011

Вы должны переопределить метод operator +, поскольку тип возвращаемого вами значения для оператора + определяется как Float32_base.Вы можете сделать это с помощью ковариации и сделать метод виртуальным.Затем переопределите метод в своем подклассе (вы, вероятно, могли бы просто вызвать метод в суперклассе).

Вы также можете сделать это с помощью шаблонов, но если вы не знакомы с шаблонами, я бы не советовал копаться вЭто.По сути, вы определяете виртуальную функцию так, как вы уже это сделали, но вместо того, чтобы возвращать Float32_base, вы возвращаете тип вашего шаблона.(до тех пор, пока ваш тип шаблона является подклассом, C ++ должен быть хорош с противоположной дисперсией).Ваш подкласс расширит базовый класс шаблоном подкласса.

...