2015-10-06 3 views
-1

В настоящий момент я использую довольно большой фрагмент кода для анализа данных. В этом коде, помимо самого анализа, я включаю некоторые функции, которые будут использоваться в анализе, некоторые функции, связанные с объектами и некоторыми глобальными переменными. Мой код имеет следующую структуру:Включить глобальные переменные в файл заголовка - C++

#include "header1.h" 
#include "header2.h" 
... 

#define global_variable_1  1 
#define global_variable_2  3 
... 

double function1(){ 
    <code> 
{ 

double function2(){ 
    <code> 
{ 

... 

main(){ 
    <code> 
} 

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

Так что я буду что-то вроде

#include "headers.h" 
#include "functions.h" 
#include "variables.h" 

main(){ 
    <code> 
} 

Мой вопрос заключается в том, что programably собственно делать это, и если есть еще один и, возможно, лучший способ включить глобальные переменные.

+0

'#define global_variable_1 = 1;' - серьезно? Это настоящий код или вы просто дали нам приблизительное? –

+0

Прекрасно добавлять эти строки препроцессора в отдельный файл .h и включать файл в заголовки. Никакой код компиляции не должен быть в файлах с самоподготовкой –

+0

@PaulR Это, по-видимому, пример для демонстрации моей «проблемы»! – Thanos

ответ

0

Если вы пытаетесь использовать переменные, которые являются глобальными, и вы знаете, что они являются постоянным значением, таким как PI, я бы воздержался от использования как локальных глобальных, так и макросов #define. Это вопрос предпочтения, но со временем я узнал, что лучше использовать и более элегантно объявлять их как static const type name; в файле заголовка и устанавливать значение соответственно в файле cpp. Я также не предпочитаю иметь кучу оборванных ценностей или основных методов, висящих вокруг, поэтому я обычно группирую подобные типы значений и методы и содержал их в классе, объявляющем их статическими. Вот пример:

Utility.h

#ifndef UTILITY_H 
#define UTILITY_H 

#include <iostream> 
#include <string> 
#include <stdio.h>  

class Utility { 
public: 
    static void pressAnyKeyToQuit(); 

    static std::string& toUpper(std::string& str); 
    static std::string& toLower(std::string& str); 

private: 
    Utility(); // Not Implemented - This class is not an object and can not be declared. 
    Utility(const Utility& c); // Copy Constructor - Not Implemented 
    Utility& operator=(const Utility&c); Assignment Operator - Not Implemented 

}; // Utility 

#endif // UTILITY_H 

Utility.cpp

#include "Utility.h" 

// ------------------------------------------------------------------------- 
// pressAnyKeyToQuit() 
void Utility::pressAnyKeyToQuit() { 
    std::cout << "Press any key to quit" << std::endl; 
    _getch(); 
} // pressAnyKeyToQuit 

// ------------------------------------------------------------------------- 
// toUpper() 
std::string& Utility::toUper(std::string& str) { 
    std::transform(str.begin(), str.end(), str.begin(), ::toupper); 
    return str; 
} // toUpper 

// ------------------------------------------------------------------------- 
// toLower() 
std::string& Utility::toLower(std::string& str) { 
    std::transform(str.begin(), str.end(), str.begin(), ::tolower); 
    return str; 
} // toLower 

Для использования этих функций здесь приводится пример:

main.cpp

#include <iostream> 
#include <string> 
#include "Utility.h" 

int main() { 

    std::string strHello("Hello World!"); 

    std::cout << strHello << std::endl; 

    std::cout << Utility::toLower(strHello) << std::endl; 
    std::cout << Utility::toUpper(strHello) << std::endl; 

    Utility::pressAnyKeyToQuit(); 

    return 0; 
} // main 

С этим типом сдерживания является незаконным, чтобы сделать это:

int main() { 
    Utility util; 

    util.pressAnyKeyToQuit(); 
} // main 

Это не потому, что конструктор утилита по умолчанию является частным или недоступен, однако любой тип функции или переменной, которая объявлена ​​как static можно вызвать через оператор разрешения области. Ниже приведен пример константных переменных, которые будут считаться глобальными.

GeneralMath.h

#ifndef GENERAL_MATH_H 
#define GENERAL_MATH_H 

class Math { 
public: 
    static const float PI; 
    static const float PI_HAVLES; 
    static const float PI_2; 
    static const float ZERO; 

    inline static bool isZero(float fValue); 

    template<typename T> 
    inline static void swap(T& value1, T& value2); 

private: 
    Math(); 
    Math(const Math& c); // Not Implemented 
    Math& operator(const Math& c); // Not Implemented 

}; // Math 

#include "GeneralMath.inl" 

void dummy(); // does nothing used to have a method in the *.cpp file 

#endif // GENERAL_MATH_H 

GeneralMath.inl

// ------------------------------------------------------------------------- 
// isZero() 
inline bool Math::isZero(float fValue) { 
    if ((fValue > -ZERO) && (fValue < ZERO)) { 
     return true; 
    } 
    return false;  
} // isZero 


// ------------------------------------------------------------------------- 
// swap() 
template<class T> 
inline void Math::swap(T& value1, T& value2) { 
    T temp; 

    temp = value1; 
    value1 = value2; 
    value2 = temp; 

} // swap 

GeneralMath.каст

#include "GeneralMath.h" 

const float Math::PI   = 4.0f * atan(1.0f); // tan(pi/4) = 1 
const float Math::PI_HALVES = 0.5f * Math::PI; 
const float Math::PI_2   = 2.0f * Math::PI; 
const float Math::ZERO   = static_cast<float>(1e-7); 

void dummy(){return;} 

Используя его в качестве примера:

main.cpp

#include <iostream> 
#include "Utility.h" 
#include "GeneralMath.h" 

int main() { 

    float value = 3.14957; 

    if (Math::isZero(value - Math::PI)) { 
     std::cout << "true" << std::endl; 
    } else { 
     std::cout << "false" << std::endl; 
    } 

    Utility::pressAnyKeyToQuit(); 

    return 0; 

} // main 

Я предпочитаю этот подход, так что, когда общие автономные методы и постоянные переменные часто используются в нескольких файлы и имеют подобную группировку, у вас нет кучи #defines или глобальных объявленных везде.

Теперь, с другой стороны, если определенный объект класса, который вы создаете, зависит от уникального для него уникального значения констант, то вы можете иметь глобальное значение в его файле * .h или * .cpp, но я все равно останусь объявите его как static const type name;

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

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

Помните, что эти классы не являются объектами, и они не могут быть построены, и все участники должны быть статичными!

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