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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
rcyn
13 / 9 / 2
Регистрация: 30.01.2014
Сообщений: 47
#1

Реализация отношения классов типа двунаправленная ассоциация, UML, порядок объявления классов, неполный класс - C++

06.02.2014, 01:23. Просмотров 1360. Ответов 4
Метки нет (Все метки)

Доброго времени суток!
Осваивая UML, решил реализовать отношение двунаправленной ассоциации по диаграмме:
Реализация отношения классов типа двунаправленная ассоциация, UML, порядок объявления классов, неполный класс
У одного владельца (Person) может быть 0...* машин (Car).
У одной машины может быть 0...1 владельцев.

Первая попытка не компилируется:

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
class Car;
 
class Person {
    vector<Car*> cars;
    string name;
public:
    string get_name() const { return name; }
    void add_car(Car* car) { 
        cars.push_back(car); 
        car->set_owner(this); 
    }
    void delete_car(Car* car) {
        for(vector<Car*>::iterator it=cars.begin(); it!=cars.end(); it++)
            if(*car == *(*it)) { 
                car->set_owner(0); 
                cars.erase(it); 
                return; 
            }
    }
};
 
class Car {
    Person* owner;
public:
    Car() : owner(0) {}
    Car(Person* person, string model = "n/a", string number = "n/a")
        :   owner(person), mod(model), num(number)
    {}
 
    Person get_owner() const { return *owner; }
    void set_owner(Person* person) { owner = person; }
 
    bool operator==(const Car& arg) {
        return ((this->mod == arg.mod)&&(this->num == arg.num));
    }
    bool operator!=(const Car& arg) {return !(*this==arg);}
    
    string mod;
    string num;
};
main():
C++
1
2
3
4
5
6
7
8
    Car* Ferrari = new Car(0,"Ferrari","LOV3K5U");
    Car* Mers = new Car(0,"Mers","C++student");
    
    Person* Dude = new Person("Jeff Lebowski");
    Dude->add_car(Ferrari);
    Dude->add_car(Mers);
    
    cout << Ferrari->get_owner()->get_name();
Вывод:
1>code.cpp(100): error C2027: использование неопределенного типа "Car"
1> code.cpp(91): см. объявление "Car"
1>code.cpp(100): error C2227: выражение слева от "->set_owner" должно указывать на тип класса, структуры или объединения либо на универсальный тип
1>code.cpp(104): error C2676: бинарный "==": "Car" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору
1>code.cpp(105): error C2027: использование неопределенного типа "Car"
1> code.cpp(91): см. объявление "Car"
1>code.cpp(105): error C2227: выражение слева от "->set_owner" должно указывать на тип класса, структуры или объединения либо на универсальный тип

Если поменять порядок объявления классов, то программа компилируется:

C++
1
2
3
4
5
6
7
8
9
10
11
12
class Person;
 
class Car {
    Person* owner;
        // . . . 
};
 
class Person {
    vector<Car*> cars;
    string name;
    // . . .
};
Я хотел спросить почему первый вариант не работает и как лучше реализовывать подобные отношения классов.
Спасибо!
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.02.2014, 01:23
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Реализация отношения классов типа двунаправленная ассоциация, UML, порядок объявления классов, неполный класс (C++):

Вынести методы из классов Panel и PictureBox (явная реализация методов базовых абстрактных классов) - C++
Тема: Множественное наследование. Явная реализация методов базовых абстрактных классов. Как вынести методы из классов Panel и...

Объявления классов - C++
Класс может быть объявлен так: class MyClass { ... }; а может быть объявлен и так typedef class

Диаграмма классов UML - C++
это тема курсовой работы. есть готовый векторный редактор, делавшийся в течение семестра, для того чтобы использовать его в курсаче. что от...

В чем преимущество объявления прототипов классов в хедере? - C++
Здравствуйте, можете подсказать, в чем преимущество объявления прототипов классов перед классом, в котором они используются? Или зачем так...

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

Может ли Visual Studio автоматически сделать UML-диаграмму классов по коду? - C++
Здравствуйте! Скажите пожалуйста может ли Visual Studio автоматически сделать диаграмму классов по коду?

4
rcyn
13 / 9 / 2
Регистрация: 30.01.2014
Сообщений: 47
06.02.2014, 01:30  [ТС] #2
Забыл: компилятор MS Visual Studio Express 2010
0
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,292
06.02.2014, 01:36 #3
Цитата Сообщение от rcyn Посмотреть сообщение
Я хотел спросить почему первый вариант не работает и как лучше реализовывать подобные отношения классов.
Спасибо!
В Person у тебя идет обращение к методу класса Car - set_owner. Такое обращение требует полного определения класса, поэтому и не компилируется. Чтобы решить проблему нужно вынести реализацию методов add_car и delete_car в место где полное определение доступно. Если делать с разбиением на h и cpp файлы, то проблема решается сама собой:
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
// A.h
class B;
 
class A
{
public:
    void use_of_b();
 
private:
    B * data;
};
 
// B.h
class A;
 
class B
{
public:
    void use_of_a();
 
private:
    A * data;
};
 
// A.cpp
 
#include <A.h>
#include <B.h>
 
void A::use_of_b()
{
    //usage
}
 
//B.cpp
 
#include <B.h>
#include <A.h>
 
void B::use_of_a()
{
    //usage
}
1
rcyn
13 / 9 / 2
Регистрация: 30.01.2014
Сообщений: 47
06.02.2014, 01:41  [ТС] #4
А какой механизм/принцип/правило обуславливает этот запрет?
Или просто нельзя и всё?
0
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,292
06.02.2014, 02:24 #5
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от rcyn Посмотреть сообщение
А какой механизм/принцип/правило обуславливает этот запрет?
Или просто нельзя и всё?
Это все есть в стандарте С++. Ну и логически тут все обосновано: вот представь: нужно вызвать некий метод у класса A, а тебе доступно только имя класса. Как по-твоему компилятор должен догадаться о сигнатуре этого метода, о том, есть ли вообще такой метод в этом классе, если нет самого определения класса?
Есть языки, которые это позволяют, скажем многие динамические языки это умеют, потому что вся информация уже загружена.
С++ статически типизированный язык и проектировался так, чтобы исключить лишние проходы компилятора по коду во время разбора исходника. Поэтому и нельзя.
1
06.02.2014, 02:24
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.02.2014, 02:24
Привет! Вот еще темы с ответами:

Реализация классов - C++
Помогите, пожалуйста, с 2-мя заданиями! 1) class A { public: A(); ~A(); private: D m_data;

Разработать иерархию классов, демонстрирующее работу с коллекцией объектов разных классов - C++
Задание: Разработать в соответствии с индивидуальным заданием иерархию классов и приложение, демонстрирующее работу с коллекцией объектов...

Реализация классов чисел - C++
есть задача по реализации 2 классов действительно и комплексного числа, при дебаги возникают непонятные мне ошибки хелп. # include...

Реализация собственных классов - C++
Разработать прогнрамму, демонстрирующую работу с объектами 2х типов: Triangle(треугольник) и Quadrate(квадрат ).Каждый объект должен иметь...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru