Классы, мешающие друг другу при компиляции - PullRequest
1 голос
/ 12 февраля 2012

Я работаю над проектом 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

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

У меня есть 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

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

Ответы [ 3 ]

1 голос
/ 12 февраля 2012

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

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

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

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

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

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

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

1 голос
/ 12 февраля 2012

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

Вы определили свои функции в вашем specificMath.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 голосов
/ 12 февраля 2012

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

#ifndef MYHEADER_H
#define MYHEADER_H

//header contents

#endif

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

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

double x = 0;

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

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

...