2015-03-31 4 views
2

У меня есть источник, который говорит мне:Объявления функции и последовательность определения

The source file that defines a function should include the header that contains that function’s declaration. That way the compiler will verify that the definition and declaration are consistent.

Я не знаю, как это правильно, какой тип «последовательность» мы говорим о? Поскольку, если определение и декларация не были согласованы в типе возвращаемого типа или типа/номера аргумента, компилятор просто подумал бы, что я объявляю отдельную функцию и ничего не проверяю вообще.

E.g. Если бы я был заголовок файла test.h:

void func(); 

и источник файла testsource.cpp:

#include <iostream> 
#include "test.h" 
using namespace std; 

void func(int x){ 
    cout << "Hello StackOverflow" << endl; 
} 

Если бы я запустить эту программу, компилятор просто думать FUNC() и FUNC (int) были разными функциями и не вызывали беспокойства о последовательности. Какую консистенцию он имеет в виду?

+0

Перегруженные функции. –

+0

C++ поддерживает перегрузку функций, поэтому эти две функции 'void func()' и 'void funct (int)' будут считаться двумя совершенно отдельными функциями после того, как их имя будет искажено. – Bregalad

+4

Используйте пространства имен. 'namespace Bob {void f(); } ', а затем в источнике' void Bob :: f (int x) {} '* не будет * компилироваться. –

ответ

3

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

Кроме, конечно, хороших стандартов кодирования.

Вы правильно, две функции с одинаковыми именами, но разные аргументы вполне приемлемы - (. До тех пор, как вы никогда не называть его), а не объявлять функцию, но никогда не определяя его

C++ компилятор не не позволяйте себе стрелять в ногу, но хорошие методы кодирования.

Теперь, когда вы отредактировали цитату из книги в вопросе, я могу указать, что в цитате сказано «должно» не «должно». Использование общего смысла не является обязательным и не обеспечивается языком. Это просто хорошая практика программирования.

Также обратите внимание, что программы типа lint могут обнаруживать и жаловаться на это, даже если компилятор этого не делает.

+0

* «Нет необходимости делать это» *, если вы не хотите называть их в другом исходном файле. –

+0

Это из C++ Primer, я буду редактировать в полной цитате. – Silversonic

+1

Я НЕ рекомендую это, но другой исходный файл может объявить метод, а затем вызвать его. Исходный файл, в котором установлен метод, не обязательно должен знать об объявлении. Как я пытался указать - это было бы глупо, но язык C++ не мешает глупости. –

1

Если у вас есть другой компилируемый модуль, который зависит от вашего func, скажем, bar.cpp определен таким образом:

#include "test.h" 

void bar() 
{ 
    func(); 
} 

Этот сборник импорта блок ваш заголовок и компилятор будет считать, что будет еще один объектный файл, который определяет то, что объявлено в этом заголовке test.h.

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

+0

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

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