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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
_20_
11 / 10 / 1
Регистрация: 29.09.2011
Сообщений: 214
#1

Можно ли объявлять объекты в заголовочном файле? - C++

11.08.2014, 19:16. Просмотров 1553. Ответов 17
Метки нет (Все метки)

main.cpp
C++
1
2
3
4
#include "aa.h"
int main(int argc, char** argv){
    return 0;
}
aa.h
C++
1
2
3
4
#ifndef e2_H_
#define e2_H_
int a=0;
#endif /* e2_H_ */
aa.cpp
C++
1
#include "aa.h"
Кликните здесь для просмотра всего текста
17:13:00 **** Incremental Build of configuration Debug for project 1 ****
Info: Internal Builder is used for build
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o main.o "..\\main.cpp"
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o aa.o "..\\aa.cpp"
g++ -o 1.exe main.o aa.o 2.o
aa.o:aa.cpp.bss+0x0): multiple definition of `a'
main.o:J:\Programming\C++\rotacja\1\Debug/../main.cpp:11: first defined here
2.o:2.cpp.bss+0x0): multiple definition of `a'
main.o:J:\Programming\C++\rotacja\1\Debug/../main.cpp:11: first defined here
collect2.exe: error: ld returned 1 exit status

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

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

Как правильно объявлять статические константные объекты в классе? - C++
В классе надо объявить статичные константные строки. Типа class A { public: static const std::string OLOLO = "ololo"; } Но так...

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

Переменная в заголовочном файле - 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 //...

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
RussBear
1 / 1 / 1
Регистрация: 06.08.2014
Сообщений: 77
11.08.2014, 19:21 #2
Цитата Сообщение от _20_ Посмотреть сообщение
Что я делаю неправильно?
А что Вы хотели сделать? Объявили и инициализировали переменную а .h файле, а зачем, почему?
0
DrOffset
7147 / 4288 / 966
Регистрация: 30.01.2014
Сообщений: 7,091
11.08.2014, 19:39 #3
Цитата Сообщение от _20_ Посмотреть сообщение
Что я делаю неправильно?
Переменная int a оказалась одновременно в двух единицах трансляции (в main.cpp и aa.cpp).
Для того, чтобы этого избежать нужно разнести определение и объявление (сейчас у тебя они, так сказать, в одном флаконе):
C++
1
2
3
4
5
6
7
8
9
10
//aa.h
#ifndef e2_H_
#define e2_H_
extern int a;
#endif /* e2_H_ */
 
//aa.cpp
#include "aa.h"
 
int a = 0;
0
_20_
11 / 10 / 1
Регистрация: 29.09.2011
Сообщений: 214
11.08.2014, 19:45  [ТС] #4
Спасибо, так получается, но можно ли как - нибудь без extern обойтись?
0
DrOffset
7147 / 4288 / 966
Регистрация: 30.01.2014
Сообщений: 7,091
11.08.2014, 19:57 #5
Цитата Сообщение от _20_ Посмотреть сообщение
Спасибо, так получается, но можно ли как - нибудь без extern обойтись?
А чем extern не устраивает? Это как раз для твоей ситуации решение.
Или конкретизируй задачу, которую решаешь, - можно будет рассмотреть другие варианты.
0
_20_
11 / 10 / 1
Регистрация: 29.09.2011
Сообщений: 214
11.08.2014, 20:02  [ТС] #6
Эта переменная будет использоваться только несколько раз, но в совершенно разных местах. Было бы хорошо, чтобы она была видна только в тех файлах, где она используется.
0
DrOffset
7147 / 4288 / 966
Регистрация: 30.01.2014
Сообщений: 7,091
11.08.2014, 20:30 #7
Цитата Сообщение от _20_ Посмотреть сообщение
Эта переменная будет использоваться только несколько раз, но в совершенно разных местах. Было бы хорошо, чтобы она была видна только в тех файлах, где она используется.
Тогда можешь прописать ее объявление (с extern естественно) непосредственно в тех файлах, где нужно. Т.е. h-файл в данном случае вообще не обязателен. Определение же оставь в каком-то одном файле.

Добавлено через 9 минут
Цитата Сообщение от _20_ Посмотреть сообщение
Было бы хорошо, чтобы она была видна только в тех файлах, где она используется.
И все равно не понятно как тебе помешает extern, ведь если ты не подключишь в какой-либо файл aa.h, то переменная a и не будет видна. А если хочется использовать только в строго фиксированных файлах, то тогда см. совет выше. Просто не делаем extern int a; в h-файле, вместо этого пишем его сразу в тех файлах, где надо.
Это должна быть именно модифицируемая из разных мест переменная?
Еще можно предложить сделать две функции интерфейсом к ней:
C++
1
2
3
4
5
6
7
8
9
// h
void set_a(int a);
int  get_a(); 
 
//cpp
static int a = 0;
 
void set_a(int v) {  ::a = v; }
int get_a() { return ::a; }
1
_20_
11 / 10 / 1
Регистрация: 29.09.2011
Сообщений: 214
11.08.2014, 20:32  [ТС] #8
Спасибо. Я слышал где - то, что глобальных переменных лучше избегать, но так и не узнал, почему. Так ли это?
Не лучше ли тогда её в абстрактный класс поместить и отсылаться к этому классу?
0
DrOffset
7147 / 4288 / 966
Регистрация: 30.01.2014
Сообщений: 7,091
11.08.2014, 20:39 #9
Цитата Сообщение от _20_ Посмотреть сообщение
Я слышал где - то, что глобальных переменных лучше избегать, но так и не узнал, почему. Так ли это?
Лучше избегать. В основном проблемы связаны с сопровождением кода и пониманием его другими людьми. Хотя есть и чисто технические проблемы, связанные с временем жизни таких переменных в разных файлах (единицах трансляции, если быть точным). Это время относительно двух разных переменных из разных файлов не определено - нельзя сказать какая когда создастся и, соответственно, уничтожится. Относительно друг друга.
Цитата Сообщение от _20_ Посмотреть сообщение
Не лучше ли тогда её в абстрактный класс поместить и отсылаться к этому классу?
Мы как-то ловко перескочили от переменных к абстрактным классам. Без сформулированной задачи здесь ничего не посоветуешь (если только ты не телепат). Ты можешь быть прав, а можешь быть и не прав, в зависимости от того, чего требует задача (именно задача, а не какой-то конкретный код, код - это лишь инструмент), которую ты решаешь.
1
_20_
11 / 10 / 1
Регистрация: 29.09.2011
Сообщений: 214
11.08.2014, 20:39  [ТС] #10
Я только начал графический движок изучать Irrlicht, переменная а - это IrrlichtDevice *device на самом деле, ну и подобные вещи вроде менеджера сцны. Хотел я её с глаз долой убрать, но чтобы всегда под рукой была. Сейчас думаю, может всё - таки лучше делать класс - обёртку с геттерами и сеттерами?
0
DrOffset
7147 / 4288 / 966
Регистрация: 30.01.2014
Сообщений: 7,091
11.08.2014, 20:50 #11
_20_,
Класс обычно лучше. Но прежде чем его (их) писать, нужно продумать архитектуру (что с чем взаимодействует, кто выделяет ресурсы, и т.д.). Если этого не сделать, то скорее всего не получится ничего хорошего. Если нет опыта в ООП, сначала лучше книжку почитать толковую по общим моментам. А для тестовых примеров для освоения API движка, как мне кажется, нет смысла городить много кода. Ведь тут главное понять принцип работы. А вот когда соберешься писать свою игру, то тут и пригодятся и знания ООП, и проработка архитектуры.
0
_20_
11 / 10 / 1
Регистрация: 29.09.2011
Сообщений: 214
12.08.2014, 02:35  [ТС] #12
Немного опыта в ООП есть, но хвалиться не буду, т.к. самоучка. Для тестовых примеров можно всё в одном файле написать, здесь я с Вами согласен. Но ведь ничего плохого не случиться, если я попутно чему - нибудь научусь? Тем более, что по теме, которую мы затронули у меня полнейшая каша в голове. Если Вы не будете против, я постараюсь с ней разобраться с Вашей помощью. Скорее всего я буду Вас о чём - то переспрашивать, но прошу Вас не серчать, это не от того, что я невнимательно Ваши посты читаю, а от того, что я в чём - то не уверен и хочу дополнительно убедиться.

Правильно ли я понял, что без использования extern не получиться сделать видимой переменную для 2х разных файлов?
0
DrOffset
7147 / 4288 / 966
Регистрация: 30.01.2014
Сообщений: 7,091
12.08.2014, 08:26 #13
Цитата Сообщение от _20_ Посмотреть сообщение
Правильно ли я понял, что без использования extern не получиться сделать видимой переменную для 2х разных файлов?
Непосредственно и одну и ту же - нет. Можно использовать статические переменные классов или функции доступа (я выше показывал), как альтернативу. Зависит от области применения и той задачи, которую мы этим кодом описываем.

Добавлено через 16 минут
Цитата Сообщение от _20_ Посмотреть сообщение
Но ведь ничего плохого не случиться, если я попутно чему - нибудь научусь?
Дык, если прочитать мой пост, то я там как раз и предлагаю попутно учиться. Только сперва по-отдельности (или чередовать). У всех конечно по-разному, но подход "в омут с головой" я считаю не очень перспективным. В смысле если браться за сложную задачу без подготовки (хотя бы минимальной) в надежде попутно во всем разобраться, то скорее всего в конце будет ждать разочарование. Дома все-таки на фундаменте строят, иначе они падают. А те, у кого все-таки хватает упорства из этого омута вылезти, все-таки довольно сильно проигрывают (в основательности знаний) тем товарищам, у которых изначально была какая-то база. Это так, из личных наблюдений.
Я убежден, что программирование имеет мало общего с шаманством, и если ты что-то делаешь, то ты должен быть уверен что это и как это работает. Поэтому я и советовал именно тот вариант, который советовал. Но выбор, как всегда, за тобой, я никого не принуждаю и, естественно, помогу тебе в любой случае, какой бы ты не выбрал
0
-=ЮрА=-
Заблокирован
Автор FAQ
12.08.2014, 09:12 #14
_20_, твою проблему можно разрулить используя namespace
//обычный namespace
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
 
namespace multiple
{
  //  namespace
  //  {
        int a = 5;
  //  }
      int getVal(){
        return a;
      }
}
 
using namespace multiple;
int main(){
    cout<<a<<endl;
    cout<<getVal()<<endl;
    return 0;
}
http://codepad.org/kXn942Gv

//анонимный namespace
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
 
namespace multiple
{
    namespace
    {
        int a = 5;
    }
      int getVal(){
        return a;
      }
}
 
using namespace multiple;
int main(){
    cout<<a<<endl;
    cout<<getVal()<<endl;
    return 0;
}
http://codepad.org/7BTJzwb0
1
_20_
11 / 10 / 1
Регистрация: 29.09.2011
Сообщений: 214
12.08.2014, 13:49  [ТС] #15
Спасибо. Подводя итог, для реализации доступа к одной и той же переменной можно использовать глобальные переменные extern (нежелательно) и пространства имён namespace. Так же можно сделать переменную статическим полем класса (можно абстрактного), не статическим полем класса, если класс - синглетон, или же приватным полем класса, а доступ раздавать друзьям.

Я ничего не пропустил?
Равносильно ли это использование namespace'ов использованию статических полей класс, или есть тут свои тонкости?
Реализованны ли в С++ внутренние классы?

2 DrOffset
Не могли бы Вы уточнить, что Вы понимаете под сложной задачей и какую именно подготовку Вы считаете минимальной? Без этого, Ваше сообщение видется мне слишком абстрактным для того, чтобы иметь практическое значение.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.08.2014, 13:49
Привет! Вот еще темы с ответами:

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

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

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

Не подключается namespace в заголовочном файле - C++
Всем доброго дня. Ситуация такая: common.h #pragma once namespace CommonSystem { class Device {


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
12.08.2014, 13:49
Ответ Создать тему
Опции темы

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