2015-03-05 7 views
0

Я не уверен, что мое описание описывает проблему соответствующим образом. Я нашел это, когда пытаюсь понять внешнюю связь и внутреннюю связь. Скажем, у меня есть проект, содержащий 2 файла:Является ли законным/хорошим поставить прототип функции, определенной в другом исходном файле (а не в заголовке)?

//A.cpp 
#include <iostream> 
void doSomething(); 
int main() 
{ 
    doSomething(); 
    return 0; 
} 

//B.cpp 
#include <iostream> 
void doSomething() 
{ 
    std::cout << "Doing it" << std::endl; 
    std::cin.get(); 
} 

Обратите внимание: ни один из двух файлов не является заголовком. Они просто предоставляют 2 единицы перевода.

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

//A.cpp 
#include <iostream> 
static void doSomething() 
{ 
    std::cout << "Doing it" << std::endl; 
    std::cin.get(); 
} 
int main() 
{ 
    doSomething(); 
    return 0; 
} 


//B.cpp 
#include <iostream> 
static void doSomething() 
{ 
    std::cout << "Doing it" << std::endl; 
    std::cin.get(); 
} 
/* some other functions that call doSomething() */ 

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

ответ

2

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

//B.h 
#ifndef B_H 
#define B_H 
void doSomething(); 
#endif 

//A.cpp 
#include <iostream> 
#include "B.h" 
int main() 
{ 
    doSomething(); 
    return 0; 
} 

//B.cpp 
#include <iostream> 
#include "B.h" 

void doSomething() 
{ 
    std::cout << "Doing it" << std::endl; 
    std::cin.get(); 
} 
+0

Ах да. Помещение прототипа функции фактически эквивалентно включению заголовка, содержащего только этот прототип. Не понял. Спасибо! –

+0

Это не просто эквивалент, но на самом деле * тот же *. Препроцессор строит это так, чтобы к тому времени, когда он был скомпилирован, он выглядит точно так же, сохранен ли вы в отдельном файле или нет. – OJFord

0

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

О связи. Чтобы использовать функцию, достаточно предоставить прототип. Обычно это делается в h-файлах, но вы можете предоставить прототип функции нестационарной функции также вручную. h - это просто протипы, которые используются для определения того, как функции выглядят как на заказ для файлов c, чтобы их использовать. Как я уже сказал, вы можете обеспечить протойпы и другим способом. Речь идет о компоновщике, чтобы связать эти функции вместе.

+0

Он не использует статические данные в рассматриваемом коде. –

+0

@NeilKirk 'static void doSomething()' –

+0

@ Zéychin Он знает, что означает статическое ключевое слово. Он хочет знать, почему код без статических работ. –