2012-02-12 2 views
1

Я работаю над проектом на C++.Классы, мешающие друг другу при компиляции

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

Мой первый вопрос: что такое расширение файла для пространства имен C++?

У меня есть файл constants.h, где я планирую сохранять глобальные константы, например PI.

Сейчас:

#include <math.h> 
const double PI = M_PI; 

У меня есть пространство имен я говорил раньше, теперь называется: specificMath.h

#include <stdlib.h> 
#include "constants.h" 
... more code 

У меня есть gaussian.cpp:

#include "gaussian.h" 
#include "specificMath.h" 
#include <iostream> 
... more code 

Этот файл содержит основную функцию, которая прямо сейчас ничего не делает, я просто не могу собрать весь проект без main ...

У меня есть gaussian.h, где я не включаю ничего, это неправильно?

Третий класс, который не имеет атрибутов, просто методов (опять же, это неправильно? Или не очень?). truncatedFunctions.cpp

#include "specificMath.h" 
#include <stdlib.h> 
#include "truncatedFunctions.h" 
#include "gaussian.h" 

using namespace specificMath; 

И его truncatedFunctions.h где, опять же, я не включая ничего.

И четвертый класс, где я включаю

#include "margin.h" //Its header, where I'm not including anything 
#include "gaussian.h" 
#include "specificMath.h" 

using namespace specificMath; 

Когда я «сделать» это, кажется, собрать хорошо, но когда дело доходит до связующей части я получаю много ошибок говорить, что вещи на моем Класс margin.cpp был сначала определен в truncatedFunctions.cpp

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

ответ

1

Когда я «сделать» это, кажется, собрать хорошо, но когда дело доходит до связующей части я получаю много ошибок, говоря, что вещи на моем классе margin.cpp были впервые определены в truncatedFunctions.cpp

Вы установили Ваши функции в вашем конкретномMath.h? Вы должны только объявить эти функции.

Например, если ваш specificMath.h содержит определение функций, такие как

#ifndef COOL_STUFF_NSPC 
#define COOL_STUFF_NSPC 
#include <iostream> 
namespace coolstuff{ 
    void print(void){std::cout << "I'm declared in a header file." << std::endl; 
} 
#endif 

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

// coolstuff.namepace.h 
#ifndef COOL_STUFF_NSPC 
#define COOL_STUFF_NSPC 
namespace coolstuff{ 
    void print(void); 
} 
#endif 

Когда вы включаете coolstuff.namespace.h, он будет объявлять только функции. И вы можете объявить одну и ту же функцию несколько раз.

// coolstuff.namespace.cpp 
#include <iostream> 
#include "cs.h" 

void coolstuff::print(void){ 
    std::cout << "Hello world!" << std::endl; 
} 

Файл .cpp содержит реализацию ваших функций. Теперь ваш линкер не будет раздражаться, потому что есть только одна реализация coolstuff::print, а не n (где n - это номер #include "cs.namespace.h").

Мой первый вопрос: что такое расширение файла для пространства имен C++?

Нет стандартного расширения пространства имен. Используйте .h /.cpp для заголовка/реализации и самоопределяемого префикса, что-то вроде «nmspc» или «nsc». Тебе решать.

0

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

#ifndef MYHEADER_H 
#define MYHEADER_H 

//header contents 

#endif 

Это предотвратит включение одного и того же заголовка дважды в одном устройстве перевода.

Во-вторых, не определяют uncosnt материал в заголовках:

double x = 0; 

это заставит все единицы перевода экспортировать этот символ.

Объявите переменную extern в своем заголовке и предоставьте определение для него в файле реализации.

+0

Нет ничего плохого в объявлениях const Constator в файлах заголовков в C++; для этого нет необходимости использовать неуклюжий «extern». Фактически, использование 'extern' может заставить компилятор пропустить оптимизацию, иначе он мог бы знать фактическое значение данных. –

+0

@GregHewgill Я этого не знал, спасибо. Я редактировал, возможно, у него есть неконстантные переменные где-то в заголовках. –

+0

С заголовком вы подразумеваете, что включает, не так ли? – coconut

1

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

Мой первый вопрос: что такое расширение файла для пространства имен C++?

В C++ файлы заголовков обычно .h или .hpp. Это не имеет значения для компилятора.

#include "gaussian.h" 
#include "specificMath.h" 
#include <iostream> 

В общем, это хорошая идея, чтобы #include материал из стандартной библиотеки первого, а затем ваши собственные вещи.

У меня есть gaussian.h, где я не включаю ничего, это неправильно?

Нет. Если вам не нужно ничего включать, не включайте ничего.

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