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

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

Войти
Регистрация
Восстановить пароль
 
beam
1 / 1 / 1
Регистрация: 22.05.2015
Сообщений: 75
#1

Не подключается namespace в заголовочном файле - C++

29.06.2016, 10:05. Просмотров 437. Ответов 10
Метки нет (Все метки)

Всем доброго дня.
Ситуация такая:
common.h
C++
1
2
3
4
5
6
7
8
#pragma once
namespace CommonSystem
{
    class Device
    {
 
    };
}
system.h
C++
1
2
3
4
5
6
7
8
9
#pragma once
#include "common.h"
namespace System
{
    class MyDevice : public CommonSystem::Device // Ругается и не дает сделать производный класс.
    {
        
    };
}
В комменте все написано. Автодополнение есть. При попытке ввода пространства CommonSystem он мне не предлагает его (не видит чтоли). После ввода :: не появляется ничего. При ручном дописывании и компиляции вылазят ошибки
  1. error: #276: name followed by "::" must be a class or namespace name
  2. error: #262: not a class or struct name

А вот в
system.cpp
C++
1
2
3
4
void foo()
{
    CommonSystem::Device dev;// Тут все работает и создается нормально
}
То же создание экземпляра класса из CommonSystem выполняется без ругани.

Что я делаю не так? Можно ли создать наследуемый класс из другого namespace?
Спасибо
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.06.2016, 10:05
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Не подключается namespace в заголовочном файле (C++):

Setlocale в заголовочном файле - C++
main.cpp #include <cstdlib> #include <iostream> #include <cstring> #include <string> #include "studio.h" using namespace...

Переменная в заголовочном файле - C++
//qwer.h class qwer { public: extern int a; }; //qwer.cpp #include "qwer.h"

Функции в заголовочном файле - C++
Почему нельза задать тело функции в .h файле??? например(header.h): #ifndef HEADER_H #define HEADER_H void f(){} #endif //...

Структура в заголовочном файле - C++
Код .h: // file.h #pragma once struct Worker { char name; int cdate; int vdate; char post;

Объявление класса в заголовочном файле - C++
Здравствуйте. Столкнулся с тем что нужно скомпилировать библиотеку для C++. классы написал, библиотеку скомпилировал. осталось только...

Создание структуры в заголовочном файле - C++
Доброго времени суток! Решил заняться разработкой приложений, сейчас делаю небольшую программу, библиотека SFML. Вопрос: Я создал...

10
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
29.06.2016, 10:17 #2
Цитата Сообщение от beam Посмотреть сообщение
common.h
Содержимое этого файла точно такое, как показано? Ничего больше в нем нет?
0
beam
1 / 1 / 1
Регистрация: 22.05.2015
Сообщений: 75
29.06.2016, 10:54  [ТС] #3
хм. Создал нулевой проект. Сделал пустые файлы как здесь, скомпилилось. Эти же записи в существующих файлах (ну там много чего еще есть, но все вроде цивильно) не компилят. Ща попробую разгрести
0
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
29.06.2016, 11:23 #4
Цитата Сообщение от beam Посмотреть сообщение
но все вроде цивильно
Наверное все-таки что-то есть. Проверь на предмет циклического включения заголовочных файлов.
1
beam
1 / 1 / 1
Регистрация: 22.05.2015
Сообщений: 75
29.06.2016, 12:36  [ТС] #5
Задефаинил половину проекта, скомпилил, но что-то другое вылезло. Разгребаю.
А как он может циклически включаться, если у меня в каждом .h стоит #pragma once ?

Добавлено через 23 минуты
Сделал. Не понял в чем была проблема. но исчезла после объявления конструктора базового класс в public

Добавлено через 3 минуты
Опана. Действительно у меня срабатывает
Цитата Сообщение от DrOffset Посмотреть сообщение
циклического включения заголовочных файло
Как это убрать? У меня получается 2 файла взаимно друг друга добавляют и, видимо, что-то ломается. Если в одном из них не включить длругого, то нельзя будет использовать его функции, но при этом компилится класс
0
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
29.06.2016, 12:47 #6
Цитата Сообщение от beam Посмотреть сообщение
А как он может циклически включаться, если у меня в каждом .h стоит #pragma once ?
Вот именно, что не может. Смотри объяснение вот тут. Если не понимать такие моменты, то программирование так и останется на уровне шаманства.

Цитата Сообщение от beam Посмотреть сообщение
но исчезла после объявления конструктора базового класс в public
Ни за что не поверю, что из-за этого первоначальная проблема решилась. Судя по ошибкам в первом посте темы, виной тому были именно циклические включения заголовочных файлов. А что касается конструкторов в public, то это конечно тоже проблема, но совершенно иная, вторичная по отношению к проблеме в стартовом посте. Ты ведь когда ошибки компилятора читаешь, наверняка понимаешь, что он выводит разные ошибки по разным причинам. И если до второй ошибки дело не дошло из-за первой, то проявится она только после, как первую исправили.

Добавлено через 3 минуты
Цитата Сообщение от beam Посмотреть сообщение
Как это убрать?
Очень просто убрать. В *.h использовать предварительные объявления, а заголовочные файл другого класса подключать в cpp, а не в h.

Добавлено через 1 минуту
А вообще это как правило плохой тон, когда базовый класс что-то знает о наследнике.
1
beam
1 / 1 / 1
Регистрация: 22.05.2015
Сообщений: 75
29.06.2016, 12:53  [ТС] #7
дада, я позже заметил, что у меня закомментены инклюды и функции который из них подтягиваются. Инклюды раскомментил и посыпались старые ошибки. Действительно циклическое включение, но как от него избавиться, если это включение нужно?

Добавлено через 3 минуты
Базовый класс о наследнике не знает ничего, но использует несколько функций из .cpp файла, в котором определяются функции класса наследника и некоторые другие функции, не относящиеся к классу, но относящиеся к устройству. Класс наследник является непосредственно экземпляром устройства. Но у него есть несколько функций не входящих в его состав. Именно они и вызываются из того .cpp файла.
0
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
29.06.2016, 12:58 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от beam Посмотреть сообщение
Действительно циклическое включение, но как от него избавиться, если это включение нужно?
Во-первых 10 раз себя спросить, действительно ли оно нужно. Если ответ да, то спросить еще раз.

Во-вторых, если все-таки нужно,то давай сюда минимальный пример использования базовым классом класса наследника в твоей системе. Подберем под него решение.

Добавлено через 1 минуту
Цитата Сообщение от beam Посмотреть сообщение
Но у него есть несколько функций не входящих в его состав.
Реализацию базового класса выносишь в cpp, .h с классом наследника подключаешь в него же. В *.h базового класса его НЕ подключаешь.

Добавлено через 1 минуту
Цитата Сообщение от beam Посмотреть сообщение
Но у него есть несколько функций не входящих в его состав.
Или другой вариант. Сделать под эти функции свой h. Затем заинклудить его в h наследника и отдельно в h базы. Сам h наследника в h базы НЕ включать.
1
beam
1 / 1 / 1
Регистрация: 22.05.2015
Сообщений: 75
29.06.2016, 13:15  [ТС] #9
Что бы было понятно:
system.h
C++
1
2
3
4
5
6
7
8
9
10
#include "my_device.h"
 
namespace System
{
    class Device
    {
    public:
        Device();
    }
}
system.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "system.h"
 
using namespace myDeviceSpace;
 
namespace System
{
    Device::Device
    {
 
    }
    void systemFoo()
    {
        foo1();
        foo2();
        foo3();
    }
{
my_device.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "system.h"
 
namespace myDeviceSpace : public System::Device
{
    class MyDevice
    {
    public:
        MyDevice();
    }
    
    void foo1();
    void foo2();
    void foo3();
}
my_device.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace myDeviceSpace
{
    MyDevice::MyDevice
    {
    
    }
    
    foo1()
    {
        
    }
    foo2()
    {
        
    }
    foo3()
    {
        
    }
}
Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Реализацию базового класса выносишь в cpp, .h с классом наследника подключаешь в него же. В *.h базового класса его НЕ подключаешь.
Сделал так - получилось. Скомпилилось все полностью

Добавлено через 6 минут
Теперь выглядит хорошо. Спасибо!!
0
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
29.06.2016, 13:15 #10
Цитата Сообщение от beam Посмотреть сообщение
Сделал так - получилось. Скомпилилось все полностью
Ну и отлично. Вот тебе темы (в том числе смежные), которые надо разобрать, чтобы все это перестало казаться магией:
* раздельная компиляция, единицы трансляции
* include guards
* ODR
* связывание (linkage) внешнее\внутреннее (internal\external)
1
beam
1 / 1 / 1
Регистрация: 22.05.2015
Сообщений: 75
29.06.2016, 13:17  [ТС] #11
хы) думал более менее разбираюсь, а все 4 пункта не знакомы.
Прочту что с чем едят. Спасибо
0
29.06.2016, 13:17
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.06.2016, 13:17
Привет! Вот еще темы с ответами:

Объявление константы в заголовочном файле - C++
Как объявить константу и массив в заголовочном файле? Map.h #pragma once #include <SFML\Graphics.hpp> extern const...

Дружественные методы в заголовочном и релизационном файле - C++
Доброго времени суток. Есть такая проблема: В заголовочном файле lsf.h описываю класс и перегружаю "<<" ">>" для работы с классом. ...

Как подключить библиотеки в заголовочном файле? - C++
Для работы заголовочного файла ("russianletters.h") необходимо дополнительно подключить библиотеки stdio.h и windows.h. В результате...

Можно ли объявлять объекты в заголовочном файле? - C++
main.cpp #include "aa.h" int main(int argc, char** argv){ return 0; } aa.h #ifndef e2_H_ #define e2_H_ int a=0; #endif...


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

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

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