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с.
... на фондовом рынке, финансовый кризис в США, негативное воздействие инфляции на эффективность работы банковской сектора способствовали тому, что вопросы теории, методологии и практики банковского риск - менеджмента стали актуальными в нашей стране. Решение любой экономической задачи должно опираться на правильное понимание сущности риска и механизма его исследования. Известно, что чем выше степень ...
... по управлению кредитной организации, не обеспечивают ясного понимания направлений расходования средств[9]. ЗАКЛЮЧЕНИЕ В соответствии с поставленной целью, сделаем основные выводы по нашей работе: - общие вопросы правового регулирования банкротства кредитных организаций прописаны в федеральном законе № 40 ФЗ «О несостоятельности (банкротстве) кредитных организаций» от 25 февраля 1999 года, ...
... и его территориальных органов 3. Полномочия по изданию нормативных и ненормативных правовых актов в сфере антимонопольного контроля 1. Система органов антимонопольного контроля Существуют специализированные органы, уполномоченные осуществлять государственную поддержку конкуренции и антимонопольный контроль: - Федеральная антимонопольная служба РФ (Постановление Правительства РФ от 30.06. ...
... фаций, урочищ и местностей. Особую роль в этом призвана сыграть систематика типологических комплексов низкого таксономического ранга: фаций, урочищ, местностей. Несмотря на то, что проблема систематики ландшафтов Центрального Черноземья уже давно привлекает внимание многих исследователей (Ф.Н. Мильков [5, 6, 7]; К.А. Дроздов [2, 3]; В.Б. Михно [11, 12] и др.) она окончательно не решена и требует ...
0 комментариев