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

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

Войти
Регистрация
Восстановить пароль
 
QGuest
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
#1

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

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

Возможно ли связать два класса реализованных в .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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.07.2014, 02:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Взаимный include без использования cpp-файлов (C++):

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

Поменять местами содержимое файлов - C++ без использования третьего файла - C++
Здравствуйте! Задача такая, поменять содержимое двух файлов без использования третьего файла. Эта задача была решена в теме по адресу...

Подключение файла #include <name.cpp> - C++
Здравствуйте. Скажите, если программа состоит из нескольких файлов, можно-ли подключать cpp - файлы, или подключать можно только хедеры? ...

Подключение файлов main.cpp some.cpp some.h - C++
Всем привет, программа разделенна на три файла poly.cpp main.cpp poly.h Кто мог бы объяснить как происходит подключение этих файлов, и как...

Библиотека (.h + .cpp) в папку include компилятора - C++
Здравствуйте! Написал библиотеку с вынесенным в разные файлы интерфейсом и реализацией (lib.h и lib.cpp), всем функциям в .h приписал...

Работа с файлами в C# с исп. библиотек #include <stdio.h> #include <stdlib.h> #include <math.h> #include <io.h> - C++
В типизированном файле записаны названия городов и их численность. Увеличить численность каждого города на 5% (Количество жителей всегда...

14
Roodey
4 / 4 / 1
Регистрация: 23.05.2013
Сообщений: 36
10.07.2014, 04:58 #2
Ну, для вызова этих модулей все-равно понадобится использование основного .cpp файла
Так что думаю, что нет, нельзя. Да и зачем?
1
ValeryS
Модератор
6673 / 5082 / 474
Регистрация: 14.02.2011
Сообщений: 17,047
10.07.2014, 07:46 #3
Цитата Сообщение от QGuest Посмотреть сообщение
чтобы не приходилось переносить реализацию в файлы cpp?
а причем здесь реализация?
они ссылаются друг на друга
да и чем плоха реализация в отдельном файле?
0
zss
Модератор
Эксперт С++
6474 / 6037 / 1980
Регистрация: 18.12.2011
Сообщений: 15,623
Завершенные тесты: 1
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
castaway
Эксперт С++
4885 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
10.07.2014, 08:41 #5
Можно. Пиши реализацию в заголовочных файлах там где у тебя комментарии.
0
Kukurudza
105 / 86 / 6
Регистрация: 29.08.2012
Сообщений: 539
10.07.2014, 08:54 #6
а компилятор не зациклится от того что два файла ссылаются друг на друга?
0
Jewbacabra
Эксперт PHP
2582 / 2176 / 816
Регистрация: 24.04.2014
Сообщений: 6,472
10.07.2014, 09:54 #7
Цитата Сообщение от Kukurudza Посмотреть сообщение
а компилятор не зациклится от того что два файла ссылаются друг на друга?
зацикливается. include guard http://ru.wikipedia.org/wiki/Include_guard помогает решить эту проблему
0
QGuest
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
castaway
Эксперт С++
4885 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
10.07.2014, 12:24 #9
Я не имел в виду твой не рабочий вариант, я имею в виду что вообще это возможно.
Твой вариант не будет работать даже в .cpp модулях. Исправляй ошибки о которых уже сказали и пиши реализацию в заголовочных файлах.
0
ValeryS
Модератор
6673 / 5082 / 474
Регистрация: 14.02.2011
Сообщений: 17,047
10.07.2014, 14:49 #10
Цитата Сообщение от castaway Посмотреть сообщение
и пиши реализацию в заголовочных файлах.
можно спросить? Зачем?
0
castaway
Эксперт С++
4885 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
10.07.2014, 15:29 #11
Спроси у ТС. Это ведь ему нужно. Я лишь говорю что это возможно.
0
ValeryS
Модератор
6673 / 5082 / 474
Регистрация: 14.02.2011
Сообщений: 17,047
10.07.2014, 16:33 #12
Цитата Сообщение от castaway Посмотреть сообщение
Спроси у ТС.
ТС не понимает куда ввязывается
написать один файл, немножко долго
но гораздо проще чем вылавливать ошибки линковки
0
Voivoid
675 / 278 / 12
Регистрация: 31.03.2013
Сообщений: 1,339
10.07.2014, 16:48 #13
Цитата Сообщение от QGuest Посмотреть сообщение
class Object
class String : public Object
virtual bool equals(Object& other) { /**/ }
ООП головного мозга
0
castaway
Эксперт С++
4885 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
10.07.2014, 16:50 #14
Я не люблю когда меня кто-то чему-то учит без моего желания, навязывает своё мнение. Ты любишь?
0
EVP
390 / 246 / 43
Регистрация: 14.12.2010
Сообщений: 472
10.07.2014, 19:10 #15
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от 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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.07.2014, 19:10
Привет! Вот еще темы с ответами:

#include<iostream>// подключение библиотек #include <conio.h> #include <climits> - C++
помогите для этой программы сделать блок-схему. Пожалуйста #include&lt;iostream&gt;// подключение библиотек #include &lt;conio.h&gt; #include...

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

Создание cpp файлов - C++
я недавно начал зучать язык программированя С++ и делаю это самостоятельно с помашю книг и интернета. я ищю статьи где было бы подробно...

Обращение файлов cpp - C++
Всем привет! Изображу наглядно код: main.cpp #include &lt;iostream&gt; using namespace std; void raznica(); void summa();


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

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

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