2016-12-22 1 views
1

У меня есть класс, который является производным от двух одинаковых оснований:В множественном наследовании от двух идентичных базовых классов, как бросить это один из тех

class Vector3d {...}; 
class Position:public Vector3d {...}; 
class Velocity:public Vector3d {...}; 

class Trajectory:public Position, public Velocity 
{ 
    Vector3d &GetPosition(void); 
    Vector3d &GetVelocity(void); 
}; 

Я хотел бы иметь функции-членов в производном классе для быстрого броска на одну или другую базу. То, что я пытаюсь это:

Vector3d &GetPosition(void) const 
{ 
    return static_cast<const Vector3d &>(*this); 
} 

, но я получил любезное сообщение от компилятора: «Reference инициализируется с„сопзИте позициями“, нуждается в объекте типа" Vector3D»

Когда я использую:

const Vector3d &GetPosition(void) const 
{ 
    return static_cast<const Vector3d &>(*this); 
} 

вещи компилировать в порядке, но я не могу использовать его в том, что я намерен:

Trajectory t; 
t.Position=Set(20,30,50); 

потому t.Po sition является const и, следовательно, неправильным значением lvalue, как компилятор сообщает.

Любые идеи относительно того, как ссылаться на базовые классы из этого в не постоянное разыменование?

+0

Не комментировать это отдельно, чтобы сказать, что дизайн здесь кажется чем-то неправильным. На самом деле легко попасть в беспорядок с наследованием. Предпочитают инкапсуляцию. Тогда проблема полностью исчезает. – Robinson

+0

вы уверены? вы сталкиваетесь с проблемой «Diamond issue», чтобы проверить, объявляет ли она переменную-член в базовом классе 'Vector3d', а затем вызывает ее из функции участника Trajectory. поэтому используйте виртуальное наследование. – Raindrop7

+0

@ Raindrop7: НЕ используйте виртуальное наследование здесь. Это похоже на проблему с алмазом, но обратите внимание, что для позиции + скорости крайне важно, чтобы эти vector3d оставались на 100% раздельными. –

ответ

5

Вы могли бы сделать

class Trajectory:public Position, public Velocity 
{ 
public: 
    Vector3d &GetPosition() { return static_cast<Position&>(*this); } 
    Vector3d &GetVelocity() { return static_cast<Velocity&>(*this); } 
}; 

Demo

но с использованием композиции вместо наследования представляется более целесообразным.

class Trajectory 
{ 
public: 
    const Position& GetPosition() const { return position; } 
    Position& GetPosition() { return position; } 
    const Velocity& GetVelocity() const { return velocity; } 
    Velocity& GetVelocity() { return velocity; } 
private: 
    Position position; 
    Velocity velocity; 
}; 
+0

что касается алмазов выпуск? – Raindrop7

+1

@ Raindrop7: это не алмаз, но Y наследство, Trajectory имеет 2 базовых vector3d, и мы должны указать, какой из них мы хотим. – Jarod42

+0

спасибо за быстрый ответ !!!! – user7328061

3

Я понимаю, скорость является вектором (v1, v2, v3), а также положение точки в 3D пространстве (p1, p2, p3). Теперь в траектории точка может иметь как скорость, так и положение, скорость и положение. Во-первых, вы не можете использовать виртуальное наследование.

Я думаю, что состав имеет больше смысла.

class Trajectory 
{ 
    public: 
    Position p; 
    Velocity v; 
}; 
Смежные вопросы