Читать интересную книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 292 293 294 295 296 297 298 299 300 ... 337
class="image">  В языке C есть альтернативное определение функции в стиле языка Algol-60, в котором типы параметров (не обязательно) указываются отдельно от их имен.

int old_style(p,b,x) char* p; char b;

{

  /* ... */

}

 

 Это определение “в старом стиле” предвосхищает конструкции языка С++ и не является прототипом. По умолчанию аргумент без объявленного типа считается аргументов типа int. Итак, параметр x является аргументом функции old_style(), имеющим тип int. Мы можем вызвать функцию old_style() следующим образом:

old_style();               /* OK: пропущены все аргументы */

old_style("hello",'a',17); /* OK: все аргументы имеют правильный тип */

old_style(12,13,14);       /* OK: 12 — неправильный тип */

                           /* но old_style() может не использовать p */

Компилятор должен пропустить эти вызовы (но мы надеемся, что он предупредит о первом и третьем аргументах).

Мы рекомендуем придерживаться следующих правил проверки типов аргументов функций.

• Последовательно используйте прототипы функций (используйте заголовочные файлы).

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

• Используйте (какую-нибудь) программу lint.

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

27.2.4. Вызов функций, написанных на языке С, из программы на языке С++, и наоборот

Вы можете установить связи между файлами, скомпилированными с помощью компилятора языка С, и файлами, скомпилированными с помощью компилятора языка С++, только если компиляторы предусматривают такую возможность. Например, можете связать объектные файлы, сгенерированные из кода на языке С и С++, используя компиляторы GNU C и GCC. Можете также связать объектные файлы, сгенерированные из кода на языке С и С++, используя компиляторы Microsoft C и C++ (MSC++). Это обычная и полезная практика, позволяющая использовать больше библиотек, чем это возможно при использовании только одного из этих языков.

 

 В языке C++ предусмотрена более строгая проверка типов, чем в языке C. В частности, компилятор и редактор связей для языка C++ проверяют, согласованно ли определены и используются функции f(int) и f(double), даже если они определены в разных исходных файлах. Редактор связей для языка C не проводит такой проверки. Для того чтобы вызвать функцию, определенную в языке C, в программе, написанной на языке C++, и наоборот, необходимо сообщить компилятору о том, что вы собираетесь сделать.

// вызов функции на языке C из кода на языке C++:

extern "C" double sqrt(double); // связь с функцией языка C

void my_c_plus_plus_fct()

{

  double sr = sqrt(2);

}

По существу, выражение extern "C" сообщает компилятору о том, что вы используете соглашения, принятые компилятором языка С. Помимо этого, с точки зрения языка С++ в этой программе все нормально. Фактически стандартная функция sqrt(double) из языка C++ обычно входит и в стандартную библиотеку языка С. Для того чтобы вызвать функцию из библиотеки языка С в программе, написанной на языке С++, больше ничего не требуется. Язык C++ просто адаптирован к соглашениям, принятым в редакторе связей языка C.

Мы можем также использовать выражение extern "C", чтобы вызвать функцию языка С++ из программы, написанной на языке С.

// вызов функции на языке C++ из кода на языке C:

extern "C" int call_f(S* p, int i)

{

  return p–>f(i);

}

Теперь в программе на языке C можно косвенно вызвать функцию-член f().

/* вызов функции на языке C++ из функции на языке C: */

int call_f(S* p, int i);

struct S* make_S(int,const char*);

void my_c_fct(int i)

{

  /* ... */

  struct S* p = make_S(x, "foo");

  int x = call_f(p,i);

  /* ... */

}

Для того чтобы эта конструкция работала, больше о языке С++ упоминать не обязательно.

Выгоды такого взаимодействия очевидны: код можно писать на смеси языков C и C++. В частности, программы на языке C++ могут использовать библиотеки, написанные на языке C, а программы на языке C могут использовать библиотеки, написанные на языке С++. Более того, большинство языков (особенно Fortran) имеют интерфейс вызова функций, написанных на языке С, и допускают вызов своих функций в программах, написанных на языке С.

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

// В языке C++:

class complex {

  double re, im;

public:

  // все обычные операции

};

Тогда можете не передавать указатель на объект в программу, написанную на языке С, и наоборот. Можете даже получить доступ к членам re и im в программе, написанной на языке C, с помощью объявления

/* В языке C: */

struct complex {

  double re, im;

  /* никаких операций */

};

 

 Правила компоновки в любом языке могут быть сложными, а правила компоновки модулей, написанных на нескольких языках, иногда даже трудно описать. Тем не менее функции, написанные на языках C и C++, могут обмениваться объектами встроенных типов и классами (структурами) без виртуальных функций. Если класс содержит виртуальные функции, можете просто передать указатели на его объекты и предоставить работу с ними коду, написанному на языке C++. Примером этого правила является функция call_f(): функция f() может быть virtual. Следовательно, этот пример иллюстрирует вызов виртуальной функции из программы, написанной на языке C.

Кроме встроенных типов, простейшим и наиболее безопасным способом совместного использования типов является конструкция struct, определенная в общем заголовочном файле языков C и C++. Однако эта стратегия серьезно ограничивает возможности использования языка С++, поэтому мы ее не рекомендуем. 

27.2.5. Указатели на функции

Что можно сделать на языке С, если мы хотим использовать объектно-ориентированную технологию (см. разделы 14.2–14.4)? По существу, нам нужна какая-то альтернатива виртуальным функциям. Большинству людей в голову в первую очередь приходит мысль использовать структуру с “полем типа” (“type field”), описывающим, какой вид фигуры представляет данный объект. Рассмотрим пример.

1 ... 292 293 294 295 296 297 298 299 300 ... 337
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп.
Книги, аналогичгные Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Оставить комментарий