2015-03-05 4 views
-1

Сейчас я создаю вектор в файле заголовка. Разумеется, я не просто объявляю это.Объявлять и инициализировать вектор в заголовке (также, другие контейнеры STL)

std::vector<int> attacked_nodes = std::vector<int>(); 

Это прекрасно работает, но это вызывает у меня некоторые сомнения. Это не в контексте правильного класса, это просто переменная, используемая многими функциями.

Я хотел бы знать, если это

  • правильно (это будет иметь неприятные последствия?)
  • приемлемой практикой (это, вероятно, не хорошо)

Я искал вокруг , да.

УВЕДОМЛЕНИЕ: это, вероятно, плохая практика кодирования, я получаю ее. Что я хочу знать, если это действительно некорректно?

Я бы предпочел не использовать новое для создания указателя, возможно, я мог бы использовать новое и сохранить ссылку? Это still inelegant, но может работать.

Спасибо.

+1

Совершенно неясно, что вы спрашиваете о самом деле. Каковы ваши особые сомнения? Точки, которые вы оставили, слишком расплывчаты. –

+0

Определение свободной переменной в файле заголовка - ужасная идея. Зачем вам это нужно? –

+0

@ πάνταῥεῖ Я инициализирую вектор в заголовке и сохраняю его как ссылку. Это приводит к неопределенному поведению или плохой практике кодирования? – Agostino

ответ

2

Вы спросили:

Я хотел бы знать, если это правильно (? Это будет иметь неприятные последствия)

Это не правильно, если вы #include заголовочных файлов в более чем один перевод. Да, это будет иметь неприятные последствия. Создание простого проекта с:

хиджры

std::vector<int> attacked_nodes = std::vector<int>(); 

a.cpp

#include "a.h" 
void foo() {} 

основной.каст

#include "a.h" 

int main() {} 

Вы увидите сообщение об ошибке компоновщика о attached_nodes определяется более чем один раз.

Вы также сказали:

это не в контексте собственного класса, это просто переменная используется многими функциями.

Когда у вас есть глобальное состояние, к которому обращаются многие функции, лучше всего обеспечить доступ к данным с помощью функционального интерфейса.

.h файл:

std::vector<int>& get_attacked_nodes(); 

В реализации:

static std::vector<int> attacked_nodes = std::vector<int>(); 
std::vector<int>& get_attacked_nodes() 
{ 
    return attacked_nodes; 
} 
+0

В настоящее время он включен только в один файл, поэтому он еще не был пойман. Спасибо за пример. – Agostino

+0

Эта ссылка не работает. –

+0

@Agostino, я использовал свое предлагаемое решение в производственном коде, и он работает хорошо. –

5

Это действительно C++, но это не хороший дизайн. Вы определяете глобальный объект в файле заголовка. В этом есть две проблемы: «глобальный» бит и бит «в заголовочном файле».

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

Теперь проблема с глобальным состоянием заключается в том, что она скрывает зависимости. Вы отмечаете, что у вас есть много функций, которые используют этот объект, но на сайте вызова этих функций не будет ясно, что они используют этот объект. Ваши функции могут возвращать разные результаты, даже если вы вызываете их с точно такими же параметрами, просто потому, что это глобальное состояние может измениться. Это плохой дизайн интерфейса и значительно усложняет выполнение функций (и доверия).

+0

Благодарим за сообщение фактического ответа. Если я собираюсь изменить рабочий код, мне нужна ясная, обоснованная причина, которая выходит за рамки «плохого» объяснения. +1 к вам. – Agostino

+0

Это не технически некорректно как таковое, но существует опасность того, что два разных модуля используют один и тот же заголовок, либо получая две копии вектора (если он объявлен статичным), либо конфликт с объявлением одного и того же вектора дважды (два определения та же переменная недействительна). –

Смежные вопросы