Присваивая определенные значения указателю this, пользователь мог управлять выделением памяти для объекта некоторого класса. В конструкторе до использования членов класса можно было с помощью такого присваивания реализовать свой алгоритм выделения памяти. Присваивая в деструкторе указателю this нуль, можно было обойти стандартную операцию освобождения объектов класса. Кроме того, присваивание нуля в деструкторе отменяло неявные вызовы деструкторов для членов и базовых классов, например:
class Z {
int z[10];
Z() { this = my_allocator(sizeof(Z)); }
~Z() { my_deallocator(this); this = 0; }
};
Если выделение памяти уже произошло (как бывает для членов и объектов auto или static), то при входе в конструктор this имеет ненулевое значение и значение нуль в противном случае.
Вызовы конструкторов для членов и базовых классов произойдут только после того, как this получил значение. Если в конструкторе базового класса есть присваивание this, то новое значение this будет использоваться и в конструкторах производных классов, если они есть.
Отметим, что при наличии указанного анахронизма или тип указателя this не может быть *const, или нужно делать исключение для this из правила о присваивании указателям со спецификацией const.
R.18.3.4 Приведение указателей на функцию-член
Указатель на функцию-член некоторого объекта можно привести к указателю на какую-то другую функцию, например (int (*) ())p-›f. Результирующий указатель будет настроен на функцию, вызов которой будет происходить с помощью обращения к этой функции-члену для того же объекта. Как обычно результат такого вызова считается неопределенным.
R.18.3.5 Невложенность классов
Если класс описан внутри другого класса и в программе больше не описано классов с этим именем, то его можно использовать, как если бы он был описан вне класса (так обстоит дело с описанием struct в С), например:
struct S {
struct T {
int a;
};
int b;
};
struct T x; // означает `S::T x;'
Список служебных слов
auto автоматический
break разрыв
case вариант
catch перехватить
char символ
class класс
const конст
continue продолжить
default по умолчанию
delete удалить
do делать
double двойной
else иначе
enum перечисление
extern внешний
float плавающий
for для
friend друг
goto переход на
if если
inline подстановка
int целый
long длинный
new новый
operator оператор
private частный
protected защищенный
public общий
register регистровый
return возврат
short короткий
signed знаковый
sizeof размер
static статический
struct структура
switch переключатель
template шаблон типа
this текущий
throw запустить
try проверить
typedef тип
union объединение
unsigned беззнаковый
virtual виртуальный
void пустой
volatile изменяемый
while пока
* ПРИМЕРЫ *
b1_1_1.cxx
#include ‹stream.hxx›
main()
{
cout ‹‹ "Hello, world\n";
}
b1_1_3.cxx
#include ‹stream.hxx›
main ()
{
int inch = 0;
cout ‹‹ "inches=";
cin ›› inch;
cout ‹‹ inch;
cout ‹‹ "in = ";
cout ‹‹ inch*2.54;
cout ‹‹ " cm\n";
}
b1_4_5v.cxx
#include ‹stream.hxx›
main()
{
const float fac = 2.54;
float x, in, cm;
char ch = 0;
for (int i= 0; i‹ 8; i++) {
cerr ‹‹ "enter length: ";
cin ›› x ›› ch;
if (ch == 'i') {// inch
in = x;
cm = x*fac;
}
else if (ch == 'c') {// cm
in = x/fac;
cm = x;
}
else
in = cm = 0;
cerr ‹‹ in ‹‹ "in = " ‹‹ cm ‹‹ " cm\n";
}
}
b1_5.cxx
#include ‹stream.hxx›
extern float pow(float, int);
main()
{
for (int i=0; i‹10; i++) cout ‹‹ pow(2,i) ‹‹ "\n";
}
extern void error(char *);
float pow(float x, int n)
{
if (n ‹ 0) {
error ("sorry, negative exponent to pow()");
return 0;
}
switch (n) {
case 0: return 1;
case 1: return x;
default: return x*pow(x,n-1);
}
}
void error(char *s)
{
cout ‹‹ s;
}
b1__13.cxx
#include ‹stream.hxx›
// 1.11
class vector {
int *v;
int sz;
public:
vector(int); // constructor
~vector(); // destructor
int size() { return sz; }
void set_size(int);
int& operator[](int);