Чтение онлайн

на главную - закладки

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

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

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

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

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”), описывающим, какой вид фигуры представляет данный объект. Рассмотрим пример.

struct Shape1 {

enum Kind { circle, rectangle } kind;

/* ... */

};

void draw(struct Shape1* p)

{

switch (p–>kind) {

case circle:

/* рисуем окружность */

break;

case rectangle:

/* рисуем прямоугольник */

Поделиться:
Популярные книги

Блуждающие огни 4

Панченко Андрей Алексеевич
4. Блуждающие огни
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Блуждающие огни 4

Я сделаю это сама

Кальк Салма
1. Магический XVIII век
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Я сделаю это сама

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Боярышня Дуняша

Меллер Юлия Викторовна
1. Боярышня
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Боярышня Дуняша

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

Леди для короля. Оборотная сторона короны

Воронцова Александра
3. Королевская охота
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Леди для короля. Оборотная сторона короны

На границе империй. Том 10. Часть 1

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 1

Черный Маг Императора 5

Герда Александр
5. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 5

Невест так много. Дилогия

Завойчинская Милена
Невест так много
Любовные романы:
любовно-фантастические романы
7.62
рейтинг книги
Невест так много. Дилогия

Идеальный мир для Социопата 3

Сапфир Олег
3. Социопат
Фантастика:
боевая фантастика
6.17
рейтинг книги
Идеальный мир для Социопата 3

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

Наследник павшего дома. Том I

Вайс Александр
1. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том I

Крещение огнем

Сапковский Анджей
5. Ведьмак
Фантастика:
фэнтези
9.40
рейтинг книги
Крещение огнем

Камень Книга двенадцатая

Минин Станислав
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Камень Книга двенадцатая