>volatile int v; // v - асинхронно-изменяемый объект типа int
>int *volatile vip; // vip - асинхронно-изменяемый указатель на тип int
>volatile int *ivp; // ivp - указатель на асинхронно-изменяемый тип int
>// vivp - асинхронно-изменяемый указатель на асинхронно-изменяемый
>// объект типа int
>volatile int *volatile vivp;
>int *ip = &v; // ошибка: нужен указатель на volatile
>*ivp = &v; // ok: ivp - указатель на volatile
>vivp = &v; // ok: vivp - volatile указатель на volatile
Подобно константам, адрес асинхронно-изменяемого объекта можно присвоить (или скопировать указатель на асинхронно-изменяемый тип) только асинхронно-изменяемому указателю. При инициализации ссылки на асинхронно-изменяемый объект следует использовать только асинхронно-изменяемые ссылки.
Между константными и асинхронно-изменяемыми объектами есть одно важное различие: для инициализации и присвоения асинхронно-изменяемых объектов не применимы синтезируемые версии операторов присвоения, копирования и перемещения. Синтезируемые функции-члены управления копированием получают параметры, типами которых являются константные ссылки на класс. Однако асинхронно-изменяемый объект не может быть передан при помощи обычной или константной ссылки.
Если класс должен обеспечить копирование, перемещение или присвоение асинхронно-изменяемых объектов в (или из) асинхронно-изменяемый операнд, в нем следует определить его собственные версии операторов копирования и перемещения. Например, объявив параметры как ссылки >const
и >volatile
, можно обеспечить копирование или присвоение из любого вида типа >Foo
:
>class Foo {
>public:
> Foo(const volatile Foo&); // копирование из объекта volatile
> // присвоение объекта volatile обычному объекту
> Foo& operator=(volatile const Foo&);
> // присвоение объекта volatile объекту volatile
> Foo& operator=(volatile const Foo&) volatile;
> // остальная часть класса Foo
>};
Хотя для объектов >volatile
вполне можно определить функции копирования и присвоения, возникает вполне резонный вопрос: имеет ли смысл копировать объект >volatile
? Ответ зависит от причины использования такого объекта в конкретной программе.
19.8.3. Директивы компоновки: >extern "C"
Иногда в программах С++ необходимо применять функции, написанные на другом языке программирования. Как правило, это язык С. Подобно любому имени, имя функции, написанной на другом языке, следует объявить. Это объявление должно указать тип возвращаемого значения и список параметров. Компилятор проверяет обращения к внешним функциям на другом языке точно так же, как и обращения к обычным функциям языка С++. Однако для вызова функций, написанных на других языках, компилятор обычно вынужден создавать иной код. Чтобы указать язык для функций, написанных на языке, отличном от С++, используются директивы компоновки (linkage directive).