Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
1

Взаимный include без использования cpp-файлов

10.07.2014, 02:45. Показов 1442. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Возможно ли связать два класса реализованных в .h-файлах, чтобы не приходилось переносить реализацию в файлы cpp?

Эти 2 класса:
Object.h
C++
1
2
3
4
5
6
7
8
class Object {
public:
    virtual String getClassName() { /**/ }
    virtual String toString() { /**/ }
    virtual bool equals(Object& other) { /**/ }
    virtual String& operator+(String& str) final { /**/ }
    friend String& operator+(String& str, Object& object) { /**/ }
}
String.h
C++
1
2
3
4
5
class String : public Object {
public:
    virtual String toString() { return *this; }
    virtual bool equals(Object& other) { /**/ }
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.07.2014, 02:45
Ответы с готовыми решениями:

Взаимный include
Здравствуйте, у меня такая проблема, есть 2 юнита и они друг-друга инклюдят, как исправить? ...

Заставить видеть .cpp файл без использования Project->Add to project
Здравствуйте. Возникла ситуация, которую хочется правильно разрешить: "Есть юнит (пусть будет юнит...

Шифрование данных без использования файлов
Всем доброго времени суток! В теме https://www.cyberforum.ru/vb-net/thread818537.html приведен...

Поиск файлов без использования класса Directory
Функции Directory.GetFiles() и Directory.GetDirectories() возвращают строковый массив со списком...

14
4 / 4 / 1
Регистрация: 23.05.2013
Сообщений: 37
10.07.2014, 04:58 2
Ну, для вызова этих модулей все-равно понадобится использование основного .cpp файла
Так что думаю, что нет, нельзя. Да и зачем?
1
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
10.07.2014, 07:46 3
Цитата Сообщение от QGuest Посмотреть сообщение
чтобы не приходилось переносить реализацию в файлы cpp?
а причем здесь реализация?
они ссылаются друг на друга
да и чем плоха реализация в отдельном файле?
0
Модератор
Эксперт С++
13507 / 10757 / 6412
Регистрация: 18.12.2011
Сообщений: 28,712
10.07.2014, 08:15 4
Странная какая-то у Вас иерархия классов.
Коли Object базовый класс, то он не может знать имени производного класса:
C++
1
2
3
4
5
6
7
8
class Object {
public:
    virtual Object& getClassName() { /**/ }
    virtual Object& toString() { /**/ }
    virtual bool equals(Object& other) { /**/ }
    virtual Object& operator+(Object& str){ /**/ }
    //friend Object& operator+(Object& str, Object& object) { /**/ }
}
А в производном классе перегружаете все эти методы и вызываете как виртуальные - по ссылке или указателю.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
10.07.2014, 08:41 5
Можно. Пиши реализацию в заголовочных файлах там где у тебя комментарии.
0
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 539
10.07.2014, 08:54 6
а компилятор не зациклится от того что два файла ссылаются друг на друга?
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
10.07.2014, 09:54 7
Цитата Сообщение от Kukurudza Посмотреть сообщение
а компилятор не зациклится от того что два файла ссылаются друг на друга?
зацикливается. include guard http://ru.wikipedia.org/wiki/Include_guard помогает решить эту проблему
0
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
10.07.2014, 12:03  [ТС] 8
Цитата Сообщение от Roodey Посмотреть сообщение
Ну, для вызова этих модулей все-равно понадобится использование основного .cpp файла
Ну это само собой понятно. Просто имел в виду, чтобы не приходилось создавать Object.cpp и String.cpp с реализацией методов (Все решения в интернете подразумевают перенос реализации в cpp). Ибо очень много неудобно будет.
Цитата Сообщение от zss Посмотреть сообщение
Странная какая-то у Вас иерархия классов.
Коли Object базовый класс, то он не может знать имени производного класса
А почему? В Java такое работает.

Цитата Сообщение от castaway Посмотреть сообщение
Можно. Пиши реализацию в заголовочных файлах там где у тебя комментарии.
Как? Компилятор ругается в Object.h на строчках где есть String, что ничего не знает про этот String
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
10.07.2014, 12:24 9
Я не имел в виду твой не рабочий вариант, я имею в виду что вообще это возможно.
Твой вариант не будет работать даже в .cpp модулях. Исправляй ошибки о которых уже сказали и пиши реализацию в заголовочных файлах.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
10.07.2014, 14:49 10
Цитата Сообщение от castaway Посмотреть сообщение
и пиши реализацию в заголовочных файлах.
можно спросить? Зачем?
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
10.07.2014, 15:29 11
Спроси у ТС. Это ведь ему нужно. Я лишь говорю что это возможно.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
10.07.2014, 16:33 12
Цитата Сообщение от castaway Посмотреть сообщение
Спроси у ТС.
ТС не понимает куда ввязывается
написать один файл, немножко долго
но гораздо проще чем вылавливать ошибки линковки
0
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
10.07.2014, 16:48 13
Цитата Сообщение от QGuest Посмотреть сообщение
class Object
class String : public Object
virtual bool equals(Object& other) { /**/ }
ООП головного мозга
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
10.07.2014, 16:50 14
Я не люблю когда меня кто-то чему-то учит без моего желания, навязывает своё мнение. Ты любишь?
0
510 / 272 / 60
Регистрация: 14.12.2010
Сообщений: 548
10.07.2014, 19:10 15
Лучший ответ Сообщение было отмечено QGuest как решение

Решение

Цитата Сообщение от QGuest Посмотреть сообщение
Ну это само собой понятно. Просто имел в виду, чтобы не приходилось создавать Object.cpp и String.cpp с реализацией методов (Все решения в интернете подразумевают перенос реализации в cpp). Ибо очень много неудобно будет.
Это специфика C++.

Цитата Сообщение от QGuest Посмотреть сообщение
Сообщение от zss
Странная какая-то у Вас иерархия классов.
Коли Object базовый класс, то он не может знать имени производного класса

А почему? В Java такое работает.
В C++ тоже работает:
Кликните здесь для просмотра всего текста
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
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <string>
 
//{{Object.h
class String;
class Object {
public:
    virtual String getClassName();
    virtual String toString();
    virtual bool equals(const Object& other);
};
//}}Object.h
 
//{{String.h
class String : public Object {
private:
    std::string value;
public:
    String(const std::string& _value):value(_value){}
    virtual String toString() override { return *this; }
    virtual bool equals(const Object& other) override{
        const String* obj = dynamic_cast<const String*>(&other);
        return (obj != nullptr) ? value == obj->value : Object::equals(other);
    }
 
    const std::string& getValue()const{ return value; }
    void setValue(const std::string& _value){ value = _value; }
 
    String operator+(const String& _value){ return String(value + _value.value); }
};
//}}String.h
 
//{{Object.cpp
String Object::getClassName() { return typeid(*this).name(); }
String Object::toString() { return std::to_string((int)this); }
bool Object::equals(const Object& other) { return this == &other; }
std::ostream& operator<< (std::ostream& stream, Object& obj)
{
    return stream << obj.toString().getValue();
}
//}}Object.cpp
 
int main()
{
    String s1("string 1");
    String s2("string 2");
    String s12(s1 + s2);
    Object o1;
 
#define PRINT_EQUALS(_s1,_s2) \
    std::cout << "\"" << _s1 << "\"" << ".equals(" << _s2 << ") ?= " << (_s1.equals(_s2)) << std::endl
 
    PRINT_EQUALS(s1, s2);
    PRINT_EQUALS(s1, s1);
    PRINT_EQUALS(s1, o1);
    PRINT_EQUALS(s12, s1+s2);
}


В данном случае порядок должен быть такой:

Обычно в *.h:
1. Объявление класса String. ( class String; )
2. Определение класса Object.
3. Определение класса String.
В определениях классов по разным причинам желательны только объявления методов и данных.

Обычно в *.cpp:
4. Определение методов класса Object;
5. Определение методов класса String;

Определение методов Object будет использовать определение класса String.
Если определение такого метода совместить с объявлением метода внутри определения класса Object,
то возникнет ошибка, т.к. доступно будет лишь объявление класса String, но не его определение.
Следовательно, его структура класса String неизвестна компилятору C++.
Поэтому определение методов выносится в файлы *.cpp,
где все определения классов будут доступны из заголовков (*.h файлов).

Компилятор Java способен откладывать компиляцию определений методов до полного определения классов,
поэтому там такой проблемы нет и разделение на *.h и *.cpp не нужно.
1
10.07.2014, 19:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.07.2014, 19:10
Помогаю со студенческими работами здесь

Аплоад файлов на сервер без использования компонент
Люди! Хочу сделать аплоад файлов на сервер без использования компонент, к сожалению провайдер не...

Проигрывание Flash-роликов без использования временных файлов
Я хочу сделать прогу, в которой будет Flash Player контрол, который будет проигрывать SWF с сервера...

Диалоги Windows API без использования файлов ресурсов
Я пытаюсь создать диалоговое окно, используя C ++ и Windows API, но я не хочу, чтобы диалоговое...

Проигрывание Flash-роликов без использования временных файлов
Я хочу сделать прогу, в которой будет Flash Player контрол, который будет проигрывать SWF с сервера...

Как просматривать GIF файлы без использования дополнительных файлов?
Как просматривать гифы без использования дополнительных файлов, со скоростью которая заложена в GIF...

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


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru