Форум программистов, компьютерный форум CyberForum.ru

Проблемы при ромбовидном наследовании - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.63
CheToZudit
9 / 9 / 2
Регистрация: 22.10.2011
Сообщений: 19
15.12.2011, 19:59     Проблемы при ромбовидном наследовании #1
У меня есть ромбовидное наследование. От Ship наследуются виртуально GuardShip и TransShip, а TransGuardShip наследуется от них.
Компилятор сообщает о такой ошибке: error C2250: TransGuardShip: неоднозначное наследование "TransShip *Ship::copy(void) const"
Причем если поменять строчку
C++
1
class TransGuardShip : public TransShip, public GuardShip
на
C++
1
class TransGuardShip : public GuardShip, public TransShip
то компилятор будет писать: error C2250: TransGuardShip: неоднозначное наследование "GuradShip *Ship::copy(void) const"

Но при этом
C++
1
2
 virtual std::ostream& show(std::ostream &) const;
virtual std::istream& get(std::istream &);
наследуются нормально. Кто-нибудь может предложить решение этой проблемы?
PS: Понимаю, что ромбовидное наследование вещь гадкая, но по условию оно должно быть

Базовый класс Судна:
C++
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#ifndef _SHIP_H_
#define _SHIP_H_
 
#include "stdafx.h"
#include <iostream>
#pragma once
#include "Captain.h"
 
//базовый класс Судно
 
 
class Ship {    
    char *name;
    Captain cap;
    int draft;      // водоизмещение
    int maxSpeed;
    int numberOfCrew;   // кол-во экипажа
protected:
    virtual std::ostream& show(std::ostream &) const;
    virtual std::istream& get(std::istream &);
    virtual Ship* copy() const = 0;
public:
    Ship() {
        name = 0;
        draft = 0;
        maxSpeed = 0;
        numberOfCrew = 0;
    }
    friend std::ostream &operator << (std::ostream &, const Ship &);
    friend std::istream &operator >> (std::istream &, Ship &);
    Ship(char *_Name, Captain _cap, int _draft, int _maxSpeed, int _numberOfCrew);
    Captain getCap() const {return cap;}
    Captain setCap();
    char *getName() const {return name;}
    char *setName();
    int getDraft() const {return draft;}
    int setDraft();
    int getMaxSpeed() const {return maxSpeed;}
    int setMaxSpeed();
    int setMaxSpeed(int);
    int getNumberOfCrew() const {return numberOfCrew;}
    int setNumberOfCrew();
};
 
#endif // _SHIP_H_

Транспортный корабль:
C++
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#ifndef _TRANS_SHIP_H_
#define _TRANS_SHIP_H_
 
#include "stdafx.h"
#include <iostream>
#pragma once
#include "Ship.h"
#include "LawOfMotion.h"
#include "BiLineLawOfMotion.h"
#include "BiSqrLawOfMotion.h"
#include "LineLawOfMotion.h"
#include "SqrLawOfMotion.h"
 
class TransShip : virtual public Ship {
    LawOfMotion *pLaw;
    int weight;
protected:
    //LawOfMotion *pLaw;
    //int weight;
    virtual std::ostream& show(std::ostream &) const;
    virtual std::istream& get(std::istream &);
    virtual TransShip* copy() const;
public:
    
    TransShip():Ship() {
        weight = 0;
        pLaw = 0;
    }
    TransShip(char *_Name, Captain _cap, int _draft, int _maxSpeed, int _numberOfCrew, int _weight, LawOfMotion *law):Ship(_Name, _cap, _draft, _maxSpeed, _numberOfCrew) {
        weight = _weight;
        pLaw = law;
    }
    LawOfMotion * getLaw() const {return pLaw;}
    int getWeight() const {return weight;}
    int setWeight();
    int getCurrentSpeed(); // изменение скорости по закону
    void setLaw(LawOfMotion *);
};
 
 
 
#endif // _TRANS_SHIP_H_

Военный корабль:
C++
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#ifndef _GUARD_SHIP_H_
#define _GUARD_SHIP_H_
#include <iostream>
#include <vector>
#pragma once
#include "stdafx.h"
#include "Ship.h"
#include "Armament.h"
 
using namespace std;
 
class GuardShip : virtual public Ship {
    //vector<Armament>::iterator p;
    vector<Armament> arma;
protected:
    virtual std::ostream& show(std::ostream &) const;
    virtual std::istream& get(std::istream &);
    virtual GuardShip* copy() const;
public:
    GuardShip():Ship() {
        vector<Armament> arma;
    }
    GuardShip(char *_Name, Captain _cap, int _draft, int _maxSpeed, int _numberOfCrew, vector<Armament> arma_):Ship(_Name, _cap, _draft, _maxSpeed, _numberOfCrew) {
        arma = arma_;
    }
    
    void addArm(const Armament& arma);
    void removeArm(Armament &arms);
    Armament &findArm(Armament &arms);
    Armament &findArm(char*);
    void getFullInfoArm(Armament &arms);
    void setFullArm(Armament &arms);
    char* setNameArm(Armament &arms) {return findArm(arms).setName();}
    char* getNameArm(Armament &arms) {return findArm(arms).getName();}
    double getCalArm(Armament &arms) {return findArm(arms).getCal();}
    double setCalArm(Armament &arms) {return findArm(arms).setCal();}
    size_t getRangeArm(Armament &arms) {return findArm(arms).getRange();}
    size_t setRangeArm(Armament &arms) {return findArm(arms).setRange();}
    location getLocArm(Armament &arms) {return findArm(arms).getLoc();}
    location setLocArm(Armament &arms) {return findArm(arms).setLoc();}
    size_t getAmmoArm(Armament &arms) {return findArm(arms).getAmmo();}
    size_t setAmmoArm(Armament &arms) {return findArm(arms).setAmmo();}
    void shootArm(Armament &arms) {findArm(arms).shoot();}
};
 
#endif // _GUARD_SHIP_H_
Военно-транспортный кораблик:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef _TRANS_GUARD_SHIP_H_
#define _TRANS_GUARD_SHIP_H_
#pragma once
 
#include "stdafx.h"
#include <iostream>
 
#include "TransShip.h"
#include "GuardShip.h"
 
class TransGuardShip : public TransShip, public GuardShip {
    std::istream& get(std::istream &);                              // show почему-то было 
    TransGuardShip* copy() const;
    std::ostream& show(std::ostream &) const;
public:
    TransGuardShip() : TransShip(), GuardShip(), Ship() {;}
    TransGuardShip(char *_Name, Captain _cap, int _draft, int _maxSpeed, int _numberOfCrew, int _weight, LawOfMotion *law, vector<Armament> arma_); //:  
    //GuardShip(_Name,  _cap, _draft, _maxSpeed,  _numberOfCrew,  arma_), 
    //TransShip(_Name,  _cap, _draft, _maxSpeed, _numberOfCrew,  _weight, law) {;}
    friend std::istream &operator >> (std::istream &is, TransGuardShip &ship);
    friend std::ostream &operator << (std::ostream &os, const TransGuardShip &ship);
};
 
#endif // _TRANS_GUARD_SHIP_H_
Добавлено через 59 минут
А может проблема кроется в том, что функция copy() является чисто виртуальной?

Добавлено через 1 час 43 минуты
Вот кстати текст самой функции copy()
C++
1
2
3
TransShip* TransShip::copy() const {
    return new TransShip(*this);
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.12.2011, 19:59     Проблемы при ромбовидном наследовании
Посмотрите здесь:

C++ Ошибка при наследовании
C++ Ошибка при наследовании
Конструкторы при наследовании C++
С++ течет при наследовании C++
C++ Ошибка при наследовании?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
H1ghlander
0 / 0 / 0
Регистрация: 11.01.2011
Сообщений: 7
28.01.2012, 11:02     Проблемы при ромбовидном наследовании #2
Столкнулся с абсолютно такой же проблемой, помогите решить. Объясните, что здесь не так, и как нужно сделать правильно.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
28.01.2012, 11:48     Проблемы при ромбовидном наследовании #3
huichos, вот минимальный код, повторяющий вашу архитектуру (именно его вы должны были привести, а не то, что есть сейчас; минимальный компилируемый (или наоборот, повторяющий ошибки) пример, без лишних деталей). Всё компилируется. Подозреваю, что это очередной косяк компилятора от МС.
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
28.01.2012, 11:50     Проблемы при ромбовидном наследовании #4
vs? если да, то меняйте компилятор. в vs до сих пор есть баг, который не позволяет переваривать подобное. хотя разработчики компилятора обещали исправить это, но пока что баг никуда не делся. gcc переваривает и не давится
silent_1991
28.01.2012, 12:05
  #5

Не по теме:

Цитата Сообщение от retmas Посмотреть сообщение
vs?
#include "stdafx.h"

retmas
28.01.2012, 12:11
  #6

Не по теме:

Цитата Сообщение от silent_1991 Посмотреть сообщение

Не по теме:


#include "stdafx.h"

такое палево и не заметил

lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
28.01.2012, 17:17     Проблемы при ромбовидном наследовании #7
На какой строке ошибка?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2012, 17:18     Проблемы при ромбовидном наследовании
Еще ссылки по теме:

Конструкторы при наследовании C++
C++ Неоднозначность при наследовании
C++ Присвоение при наследовании

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
28.01.2012, 17:18     Проблемы при ромбовидном наследовании #8
lemegeton, не на какой, как выяснилось. Ошибка из-за бака мелкомягкого компилятора.
Yandex
Объявления
28.01.2012, 17:18     Проблемы при ромбовидном наследовании
Ответ Создать тему
Опции темы

Текущее время: 21:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru