3. public int m1;

4. public string s1;

5.}

6....

7.MyStruct ms1;

8.MyStruct ms2 = new MyStruct();

9.

10.Console.WriteLine(ms1.m1);

11.Console.WriteLine(ms2.m1);

12....

13.

В чем отличие между объявлениями в строках 7 и 8? Некоторые считают, что в первом случае (строка 7) объект создается на стеке, а во втором (строка 8) происходит упаковка и объект создается в куче. На самом деле это не так. В обоих случаях объект создается на стеке. Разница в том, что в строке 7 будет создан неинициализированный объект, а в строке 8 инициализированный. Поля ms2 будут содержать значения по умолчанию (0 для m1 и null для s1), а поля ms1 неопределены. Поэтому в строке 10 возникнет ошибка компиляции.

Теперь рассмотрим нюансы, связанные с упаковкой и распаковкой. Как известно, размерные типы могут наследоваться от интерфейсов (имплиментировать интерфейсы). Часто спрашивают, будет ли производиться упаковка при приведении размерного типа к интерфейсу. Правильный ответ - да, будет, т.к. интерфейс является ссылочным типом.

Рассмотрим пример:

1.int i = 1;

2.Console.WriteLine(i.ToString());

3.Console.WriteLine(((IFormattable)i).ToString());

4.Console.WriteLine("{0}", i);

5.

Размерный тип int имплиментирует интерфейс IFormattable, содержащий метод ToString(). Так как метод ToString() является частью класса int, а компилятор знает, что это размерный тип и, следовательно, виртуальный метод ToString() не может быть переопределен (т.к. структурный тип является запечатанным), компилятор вставляет непосредственный вызов метода в строку 2 и упаковки не происходит. В строке 3 происходит упаковка, т.к. i приводится к интерфейсу IFormattable. Теперь вы сами можете сказать, что происходит в строке 4: неявное приведение к интерфейсу IFormattable и вызов метода ToString(), что, также, приводит к упаковке.

И еще один момент. Массивы являются ссылочными типами, но могут содержать размерные. Где же будет размещен, например, массив целых чисел? В куче, причем целые числа будут неупакованными.

Значением this. Для класса:

class Indirect

{

//...

public void Method(Indirect that)

{ RefParameter(ref this); // compile-time error

OutParameter(out this); // compile-time error

this = that; // compile-time error

}

//...

}

Для структуры:

struct Direct

{

//...

public void Reassign(Direct that)

{

RefParameter(ref this); // compiles ok

OutParameter(out this); // compiles ok

this = that; // compiles ok

}

//...

}

Структура не может быть null, и вот это не пройдет:

if (s == null) ... // compile-time error, where s - struct

Структуру не можно использовать с оператором as

Direct no = s as Direct; // compile-time error, where Direct - struct

Структуру не можно использовать с оператором lock

lock(s) { ... } // compile-time error, where s - struct

Не может иметь полей типа volatile (Ключевое слово volatile указывает, что поле может быть изменено несколькими потоками, выполняющимися одновременно.)

private volatile Direct field; // compile-time error, where Direct - struct

Только структру могу работать с указателями, примеры

(Ключевое слово unsafe обозначает небезопасный контекст, необходимый для работы с указателями.)

Direct variable = new Direct();

unsafe {

Direct * ptr = &variable; // compiles ok

//...

}

но с классом

Indirect variable = new Indirect();

unsafe {

fixed(Indirect * ptr = &variable) // compile-time error

{

//...

}

}

а так же

Direct * array = stackalloc Direct[42]; // compiles ok

Только структуры могу использовать sizeof

int size = sizeof(Direct); // compiles ok

По разному работает сравнение Equals

struct Direct

{

public Direct(int value)

{

field = value;

}

private int field;

}

class Indirect

{

public Indirect(int value)

{

field = value;

}

private int field;

}

class EqualsBehavior

{

static void Main()

{

Direct s1 = new Direct(42);

Direct s2 = new Direct(42);

Indirect c1 = new Indirect(42);

Indirect c2 = new Indirect(42);

bool structEquality = s1.Equals(s2); // true

bool classIdentity = c1.Equals(c2); // false

}

}

7. Что такое виртуальная функция? Приведите пример. В каких случаях используются виртуальные функции?

В случае переопределяемых функций компилятор умеет отличать один вызов от другого по типу их аргументов. Используя эту информацию, он "жестко" связывает коды программы с соответствующими функциями элементами. С другой стороны, бывает необходимо отличить один вызов от другого, при наличии аргументов одного типа на этапе выполнения, и обеспечить потомки класса разными версиями функций базового класса. Именно использование ключевого слова virtual приводит к отсрочке связывания, и вызову нужной функции на этапе выполнения.

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

Синтаксис определения виртуальных функций элементов очень прозрачный: добавьте слово virtual к первому определению функции элементу: virtual void Show(); virtual void Hide();

Только встроенные функции элементы могут быть объявлены как виртуальные. Как только функция объявлена виртуальной, она не может быть переопределена ни в каком наследуемом классе с однотипным перечнем аргументов, но с другим типом возвращаемого значения. Если вы переопределяете Show с тем же перечнем однотипных аргументов и таким же типом возвращаемого значения, то новая функция Show автоматически становится виртуальной, независимо от того, используется ключевое слово virtual или нет. В этом случае говорят, что новая виртуальная Show замещает Show в своем базовом классе. Вы можете свободно переопределять Show с другим перечнем разнотипных аргументов (изменяя при этом тип возвращаемого значения или нет), но виртуальный механизм не задействуется для такой версии Show. акая именно функция элемент Show будет вызвана - зависит только от класса объекта, для которого вызывается Show, даже если вызов производится через указатель на базовый класс. Например,

Circle ACircle

Point* APoint_рointer = &ACircle; // указатель на Circle,

// которому присваивается

// значение указателя на

// базовый класс, Point

APoint_рointer->Show(); // вызывает Circle::Show!

Так как вызов невиртуальной функции-элемента выполняется несколько быстрее, чем виртуального, то в общем случае рекомендуется, когда не встает вопрос о расширяемости, но существенное значение имеет производительность, пользоваться обычными функциями элементами. В противном случае, нужно пользоваться виртуальными.


Литература

 

1.  Баженова И. Ю. С++ && Visual Studio NET. Самоучитель программиста. - М.: КУДИЦ-ОБРАЗ, 2003. - 448с.

2.  Гилберт Стивен, Макартни Билл. Самоучитель Visual C++ 6 в примерах. - К.: ООО "ТИД ДС", 2003. - 496с.

3.  Касаткин А.И., Вальвачев А.Н. Профессиональное программирование на языке Си: От Турбо Си к С++. – Минск: Вышэйшая школа, 1992. – 240с.

4.  Николенко Д. В. Самоучитель по Visual C++. - СПб : Наука и техника, 2001. -368 с.

5.  Павловская Т.А. С/С++. Программирование на языке высокого уровня. – СПб.: Питер, 2003. – 461с.

6.  Паппас К., Мюррей У. Программирование на С и С++. - К.: BHV, 2000. – 320c.

7.  Савич У. С++ во всей полноте. - К.: BHV; СПб: Питер, 2005. 784 с.

8.  Холзнер С. Visual C++: Учебный курс. СПб: Питер, 2000. - 576с.

9.  Уэйт М., Прата С., Мартин Д. Язык Си. Руководство для начинающих. – М.: Мир, 1988. -512с.

10.  Шиманович Е.Л. C/C++ в примерах и задачах. - Минск: Новое знание, 2004, - 528с.

11.  Шмидский Я. К. Программирование на языке С/С++. Самоучитель. –М.: Вильямс, 2004. -352с.


Информация о работе «Актуальные вопросы в работе с С++»
Раздел: Информатика, программирование
Количество знаков с пробелами: 43190
Количество таблиц: 1
Количество изображений: 3

Похожие работы

Скачать
24808
0
0

... на фондовом рынке, финансовый кризис в США, негативное воздействие инфляции на эффективность работы банковской сектора способствовали тому, что вопросы теории, методологии и практики банковского риск - менеджмента стали актуальными в нашей стране. Решение любой экономической задачи должно опираться на правильное понимание сущности риска и механизма его исследования. Известно, что чем выше степень ...

Скачать
10354
0
0

... по управлению кредитной организации, не обеспечивают ясного понимания направлений расходования средств[9]. ЗАКЛЮЧЕНИЕ В соответствии с поставленной целью, сделаем основные выводы по нашей работе: - общие вопросы правового регулирования банкротства кредитных организаций прописаны в федеральном законе № 40 ФЗ «О несостоятельности (банкротстве) кредитных организаций» от 25 февраля 1999 года, ...

Скачать
78189
4
0

... и его территориальных органов 3. Полномочия по изданию нормативных и ненормативных правовых актов в сфере антимонопольного контроля 1. Система органов антимонопольного контроля Существуют специализированные органы, уполномоченные осуществлять государственную поддержку конкуренции и антимонопольный контроль: - Федеральная антимонопольная служба РФ (Постановление Правительства РФ от 30.06. ...

Скачать
22178
0
0

... фаций, урочищ и местностей. Особую роль в этом призвана сыграть систематика типологических комплексов низкого таксономического ранга: фаций, урочищ, местностей. Несмотря на то, что проблема систематики ландшафтов Центрального Черноземья уже давно привлекает внимание многих исследователей (Ф.Н. Мильков [5, 6, 7]; К.А. Дроздов [2, 3]; В.Б. Михно [11, 12] и др.) она окончательно не решена и требует ...

0 комментариев


Наверх