Поменяйте местами общепринятые функции в C ++ - PullRequest
1 голос
/ 10 мая 2011

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

void doSomething(mxArray *in)
{
    mexPrintf("Hello Matlab");
}

, тогда как mxArray и mexPrintf определены в другом файле из matlab (mex.h).В основном файле у меня сейчас:

#include "mex.h"
#include "_general.h"

, и мне интересно, что я не получил никаких ошибок компилятора, если не включить mex.h в _general.cpp также потому, что сам файл явно НУЖЕН.Не лучше ли включить или не имеет значения, в этом случае оно включено ПОСЛЕ того, как mex.h уже был включен в основной файл?

Спасибо!

Ответы [ 2 ]

4 голосов
/ 10 мая 2011

C ++ (в отличие от C) откажется делать сомнительные предположения о сигнатуре функций, для которых он не видел объявления, и компиляция завершится неудачно с сообщением об ошибке.Если вы не получили ошибку, то какой-то заголовок выбирает объявление для этой функции.Если вы не можете его найти, попробуйте запустить только этап препроцессора (например, для GCC вы бы использовали g++ -E) и проверить вывод, чтобы увидеть объявление ... ваш компилятор может оставлять комментарии о том, какой файл содержит битыкод, который может быть полезен для понимания ситуации.

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

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

3 голосов
/ 10 мая 2011

Как отметил Тамас, директива # include буквально включает заголовочный файл в ваш исходный код.Вы можете проверить это с помощью препроцессора (часть gcc)

$ cat a.cpp
#include "b.h"
int main() {
    return b();
}
$ cat b.h
#ifndef _B_H
#define _B_H

int b()
{
    return 0;
}

#endif
$ cpp a.cpp
# 1 "a.cpp"
    # 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.cpp"
# 1 "b.h" 1



int b()
{
    return 0;
}
# 2 "a.cpp" 2
int main() {
    return b();
}
$

. Как видите, если вы включаете один и тот же файл дважды (что часто бывает в любой умеренно сложной программе, включающей несколько исходных файлов)), вы сталкиваетесь с проблемой определения одной и той же функции дважды.Для решения этой проблемы стандартным способом является использование 'include guard' ( # ifndef , # define и # endif in bh ).Таким образом, всякий раз, когда вы включаете bh, определяется константа.Когда вы снова включаете bh, препроцессор проверяет эту константу и решает не включать ее снова.

Конечно, нужно быть осторожным при выборе имени константы:)

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

HTH!

...