Углубленное изучение отдельного раздела: стандартные классы С++
Курсовой проект - Компьютеры, программирование
Другие курсовые по предмету Компьютеры, программирование
?а. Применяется в C++ для передачи объектов в функции по значению.
Конструктор копирования в основном необходим, когда объект имеет указатели на объекты выделенные в куче. Если программист не создаёт конструктор копирования, то компилятор создаст неявный конструктор копирования, который копирует указатели как есть, то есть фактическое копирование данных не происходит и два объекта ссылаются на одни и те же данные в куче. Соответственно попытка изменения копии повредит оригинал, а вызов деструктора для одного из этих объектов при последующем использовании другого приведёт к обращению в область памяти, уже не принадлежащую программе.
. Аргумент должен передаваться именно по ссылке, а не по значению. Это вытекает из коллизии: при передаче объекта по значению (в частности, для вызова конструктора) требуется скопировать объект. Но для того, чтобы скопировать объект, необходимо вызвать конструктор копирования.
. Конструктор, принимающий один аргумент. Задаёт преобразование типа своего аргумента в тип конструктора. Такое преобразование типа неявно применяется только если оно уникально.
Конструктор не бывает виртуальным в смысле виртуального метода - для того, чтобы механизм виртуальных методов работал, нужно запустить конструктор, который автоматически настроит таблицу виртуальных методов данного объекта.
Виртуальными конструкторами называют похожий, но другой механизм, присутствующий в некоторых языках - например, он есть в Delphi, но нет в C++ и Java. Этот механизм позволяет создать объект любого заранее неизвестного класса при двух условиях:
этот класс является потомком некоего наперёд заданного класса (в данном примере это класс TVehicle);
на всём пути наследования от базового класса к создаваемому цепочка переопределения не обрывалась. При переопределении виртуального метода синтаксис Delphi требует ключевое слово overload, чтобы старая и новая функции с разными сигнатурами могли сосуществовать, override для переопределения функции либо reintroduce для задания новой функции с тем же именем - последнее недопустимо.
Например:= classCreate; virtual;;= class (TVehicle)Create; override;;= class (TVehicle)Create; override;; = class (TMotorcycle) // обрываем цепочку переопределения - заводим новый Create
constructor Create(x : integer); reintroduce;
end;
В языке вводится так называемый классовый тип. Этот тип в качестве значения может принимать название любого класса, производного от TVehicle.
type= class of TVehicle;
Такой механизм позволяет создавать объекты любого заранее неизвестного класса, производного от TVehicle.
var: CVehicle;: TVehicle;:= TAutomobile;:= cv.Create;
Заметьте, что код
cv := TMoped;
v := cv.Create;
является некорректным - директива reintroduce разорвала цепочку переопределения виртуального метода, поэтому будет вызван конструктор TMotorcycle.Create (а значит, будет создан мотоцикл, а не мопед!)
Имя конструктора должно совпадать с именем класса. Допускается использовать несколько конструкторов с одинаковым именем, но различными параметрами.ClassWithConstructor {:
/* Инициализация внутреннего объекта с помощью конструктора */
ClassWithConstructor(float parameter): object(parameter) {}/* вызов конструктора AnotherClass(float); */:
AnotherClass object;
};
ОПРЕДЕЛЕНИЕ
класс конструктор шаблон доступ
Приведем пример определения класса:
class TCounter {count; // данные класса: GetValue(); //функции-члены класса
void SetValue(long);
};
Определение класса начинается с ключевого слова class за которым следует имя класса. Имя класса может иметь до 32 символов, причем различаются строчные и прописные буквы. Открывающая и закрывающая фигурные скобки определяют тело класса, в которое включено описание данных и функций класса. Заканчивается описание класса символом ;. Класс имеет столько переменных (данных), сколько необходимо. Переменные могут быть любого типа, включая другие классы, указатели на классы и указатели на динамически распределяемые объекты. Переменные объявленные внутри класса имеют область видимости класса, т.е. от точки объявления переменной до конца класса.
Определение функций - членов класса.
В приведенном выше описании класса функции класса только объявлены, приведем их реализацию. Обычно описания классов включают в заголовочные файлы (*.H), а реализацию функций-членов классов - в файлы *.CPP.
// установить значение счетчикаTCounter::SetValue(long val) {
count = val;
}
//получить значение счетчикаTCounter::GetValue() { return count; }
В приведенной реализации запись TCounter:: сообщает компилятору, что реализация функций принадлежит классу TCounter. Символ :: является операцией определения области действия.
Друзья
Спецификаторы доступа позволяют указать, к каким элементам класса могут обращаться функции, в него не входящие. Однако могут быть случаи, когда целесообразно разрешить некоторому классу или функции обращаться к закрытым или защищенным элементам данного класса. Это можно сделать с помощью ключевого слова friend.
Друзьями класса могут быть объявлены другие классы или отдельные функции, как обычные, так и являющиеся элементами некоторых классов. Друзья могут объявляться в любом из разделов определения класса (закрытом, защищенном или открытом), - в каком именно, не имеет значения. В любом случае дружественный класс или функция будет иметь полный доступ к элементам класса.
Вот пример объявления Друзей класса:
class SomeClass (class AnotherClass;void regularFunc (int);void OtherClass::MemFunc(double);
//...
};
Следует иметь в виду такие правила:
Дружественность не обратима: если А объявляет В другом, это не значит, что А будет другом В. Дружба дару?/p>