Правила для конструкторов

4.3 Конструкторы и деструкторы класса

Любой переменной, участвующей в работе программы, требуется память и некоторое начальное значение. Для переменных встроенных типов размещение в памяти обеспечивается компилятором. Для локальных переменных память выделяется из стека программы и занимается для хранения значения данной переменной до тех, пока не закончится время ее жизни. Сложные типы данных также должны размещаться в памяти и уничтожаться когда их время жизни закончилось. Это осуществляется с использованием конструкторов и деструкторов.

Конструктор (constructor) — это функция-член, имя которой совпадает с именем класса, инициализирующая переменные-члены, распределяющая память для их хранения (new).

// конструктор по умолчанию Lens(); // полный конструктор Lens(double r1, double r2, double D, double d, double n); // конструктор копирования Lens(const Lens& one);

Деструктор (destructor) — это функция-член, имя которой представляет собой ~имя класса, предназначенная для уничтожения переменных (delete).

~Lens(); // деструктор

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

4.3.1. Конструкторы

Конструктор по умолчанию

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

// описание конструктора по умолчанию Lens(); // реализация конструктора по умолчанию Lens::Lens() { m_R1=0.; m_R2=0.; m_d=0.; m_D=0.; m_n=1.; }

При создании любого экземпляра класса вызывается конструктор. Если при описании экземпляра не указываются никакие параметры – вызывается конструктор по умолчанию:

// вызов конструктора по умолчанию Lens test_lens1; Lens test_lens2(); Lens test_lens3[10][10];

Полный конструктор

Полный конструктор позволяет явно инициализировать все переменные-члены класса.

// описание полного конструктора Lens(double r1,double r2,double D, double d, double n); // реализация полного конструктора Lens::Lens(double r1, double r2, double D, double d, double n) { m_R1=r1; m_R2=r2; m_d=d; m_D=D; m_n=n; }

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

// вызов полного конструктора Lens test_lens(10., -10., 2., 5., 1.5);

Неполный конструктор

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

// описание неполного конструктора Lens(double r1, double r2); // реализация неполного конструктора Lens::Lens(double r1, double r2) { m_R1=r1; m_R2=r2; m_d=0.; m_D=0.; m_n=1.; } // вызов неполного конструктора Lens lens(10., -10.);

Инициализация переменных-членов класса в конструкторах может осуществляться не только в теле конструктора, но и после оператора :. При этом, во время присваивания переменной-члену значения, будет вызываться не оператор присваивания, а конструктор. Для встроенных типов данных, таких как double или int, это не существенно, но если членами класса являются абстрактные типы, вызов конструктора вместо оператора присваивания будет выполняться быстрее.

Lens::Lens(double r1, double r2) : m_R1(R1) , m_R2(R2) { m_d=2.; m_D=5.; m_n=1.5; }

или такой вариант:

Lens::Lens(double R1, double R2) : m_R1(R1) , m_R2(R2) , m_d(2.) , m_D(5.) , m_n(1.5) { }

Конструктор копирования

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

// описание конструктора копирования Lens(const Lens& l); // реализация конструктора копирования Lens::Lens(const Lens& l) : m_R1(l.m_R1) , m_R2(l.m_R2) , m_d(l.m_d) , m_D(l.m_D) , m_n(l.m_n) { } // вызов конструктора копирования Lens lens1(10., -10.); Lens lens2(lens1);

4.3.2. Деструктор (пример 4.4. Конструктор и деструктор класса Матрица)

Деструктор осуществляет освобождение памяти, например уничтожение объектов размещенных динамически.

В классе Lens никакого динамического размещения не происходило, поэтому деструктор будет пустой, но его наличие все равно обязательно. Для примера реализации деструктора, представим, что имеется класс Matrix, который в конструкторе динамически создает двумерный массив размерности n x m. Тогда деструктор должен освобождать память, которую выделяет конструктор.

Конструктор вызывается в момент создания переменной, деструктор вызывается когда время жизни переменной закончилось, то есть когда встречается закрывающая фигурная скобка } блока, в которой была объявлен экземпляр класса, либо когда вызывается оператор delete при динамическом размещении экземпляра класса.

/////////////////////////////////////////////////////////////////////////////// Прикладное программирование// Пример 4.4. Класс Матрица// matrix.h// // Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru// Университет ИТМО/////////////////////////////////////////////////////////////////////////////// проверка на повторное подключение файла#if !defined MATRIX_H#define MATRIX_H /////////////////////////////////////////////////////////////////////////////// класс МатрицаclassMatrix { private: //число строк и число столбцовint m_rows, m_cols; //указатель на динамический массив данныхdouble* m_data; public: //конструктор по умолчанию Matrix(); //полный конструктор Matrix(int rows, int cols); //деструктор ~Matrix(); // … }; /////////////////////////////////////////////////////////////////////////////#endif //defined MATRIX_H

 

/////////////////////////////////////////////////////////////////////////////// Прикладное программирование// Пример 4.4. Класс Матрица// matrix.cpp// // Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru// Университет ИТМО/////////////////////////////////////////////////////////////////////////////#include <iostream>usingnamespace std; // подключение описания класса#include "matrix.h"/////////////////////////////////////////////////////////////////////////////// конструктор по умолчанию Matrix::Matrix() : m_rows(0) , m_cols(0) , m_data(NULL) { } /////////////////////////////////////////////////////////////////////////////// полный конструктор Matrix::Matrix(int rows, int cols) : m_rows(rows) , m_cols(cols) { m_data=newdouble [rows*cols]; for(int i=0; i<m_rows*m_cols; i++) { m_data[i] = 0.; } } ///////////////////////////////////////////////////////////////////////////////деструктор Matrix::~Matrix() { if(m_data != NULL) { delete [] m_data; } } /////////////////////////////////////////////////////////////////////////////

 

/////////////////////////////////////////////////////////////////////////////// Прикладное программирование// Пример 4.4. Класс Матрица// test_matrix.cpp// // Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru// Университет ИТМО/////////////////////////////////////////////////////////////////////////////// подключение описания класса#include "matrix.h"/////////////////////////////////////////////////////////////////////////////void main() { // в момент создания матрицы вызывается конструктор по умолчанию Matrix a; // в момент создания матрицы 3х3 вызывается полный конструктор Matrix b(3,3); // … }// время жизни переменных a и b заканчивается, вызывается деструктор/////////////////////////////////////////////////////////////////////////////

4.3.3. Проверка правильности параметров. Исключительные ситуации

Конструкторы должны проверять передаваемые им аргументы на корректность значений. Например, показатель преломления не может быть меньше 1. Что делать, если в конструктор были переданы неправильные параметры? Для этого в языке С++ существуют исключительные ситуации.

Класс exception является стандартным базовым классом C++ для всех исключений. Исключения можно сгенерировать в случае возникновения непредвиденной ошибки, например мы предполагаем что при вызове класса Lens никто не будет пытаться задать показатель преломления меньше 1, но при этом такая ситуация возможна, и это может привести к ошибке. Сгенерировать исключительную ситуацию можно при помощи оператора throw:

if(n<1) throw exception("Index of refraction should be greater than 1.");

Для обработки возникшей исключительной ситуации используются try и catch блоки.

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

// полный конструктор Lens::Lens(double r1,double r2,double D,double d,double n) : m_r1(r1) , m_r2(r2) , m_d(d) , m_D(D) , m_n(n) { if(n<1) throw exception("Index of refraction should be greater than 1."); CalculateParaxial(); } … //—————————————————————-// в случае возникновения исключительной ситуации внутри блока try // управление переходит к блоку catchtry { Lens lens7(100., -100., 50., 5., 0.); parax=lens7.GetParaxial(); parax.write(cout); } // блок catch — обработка ошибкиcatch(exception& error) { // вывод на экран сообщения об ошибке cout<<error.what()<<endl; } …

Если при выполнение какого-то оператора из блока try возникает исключение – управление сразу переходит к блоку catch. В блоке catch в скобках указывается тип исключения (exception это наиболее общий вид исключения, возможны и другие типы) и имя исключения. Внутри блока catch необходимо обработать ошибку. В нашем случае мы просто выводим на экран сообщение, в каких-то случаях потребуется более сложная обработка. Функция what() содержит текст, сгенерированный в момент создания исключения.

В результаты выполнения данного блока программы на экран выведется сообщение " Index of refraction should be greater than 1.".

Если никаких исключений в try-блоке не происходит, программа игнорирует его catch-обработчик.

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

Конструкторы (C++)

В принципе, по умолчанию ctor является ctor без аргументов.

ПОЖАЛУЙСТА, обратите внимание, что компилятор не будет генерировать любое значение по умолчанию ctor в следующем случае:

Причина, заключающаяся в том, что компилятор не видит необходимости инициализировать указатель, предоставленный программистом. Ответственность программиста заключается в правильной записи и инициализации по умолчанию ctor.

Если вы, с другой стороны, напишите виртуальную функцию внутри вышеуказанного класса, компилятор определенно будет генерировать по умолчанию ctor (но не будет инициализировать указатель iHahaptr для вас). Кроме того, такой ctor будет генерироваться ТОЛЬКО, ЕСЛИ экземпляр этого объекта был создан в программе (иначе, опять же, ctor не будет сгенерирован компилятором).

Это ТОЛЬКО 4 условия, в которых компилятор будет НЕВОЗМОЖНО генерировать по умолчанию ctor (если не предоставляется программистом):

Во всех остальных случаях компилятор не будет генерировать любой по умолчанию ctor.

ответ дан Viren 29 янв. '11 в 15:24

источникподелиться

Правила для конструкторов

Конструкторы

97

C# — Руководство по C# — Конструкторы

Конструктор инициализирует объект при его создании. У конструктора такое же имя, как и у его класса, а с точки зрения синтаксиса он подобен методу. Но у конструкторов нет возвращаемого типа, указываемого явно. Ниже приведена общая форма конструктора:

доступ имя_класса(список_параметров) { // тело конструктора }

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

Каждый класс C# снабжается конструктором по умолчанию, который при необходимости может быть переопределен. По определению такой конструктор никогда не принимает аргументов. После размещения нового объекта в памяти конструктор по умолчанию гарантирует установку всех полей в соответствующие стандартные значения. Если вы не удовлетворены такими присваиваниями по умолчанию, можете переопределить конструктор по умолчанию в соответствии со своими нуждами.

Конструктор также может принимать один или несколько параметров. В конструктор параметры вводятся таким же образом, как и в метод. Для этого достаточно объявить их в скобках после имени конструктора.

Давайте рассмотрим применение конструкторов на примере:

Как видите, в данном примере поля экземпляра класса ex инициализируются по умолчанию с помощью конструктора.

Наш любимый хостинг

Конструкторы и деструкторы

Обновление – пожалуйста, посмотрите на мой ответ на ссылку и объяснение решения этой проблемы

Прежде чем мы начнем, я знаю, что это очень общий вопрос, и я использую Ninject для многих лун без проблем, но сейчас это произошло и я не могу понять, исправить. Также, нет, ни один из результатов на Google, и так до сих пор, помогают мне.

Итак, рассмотрим следующий кусок кода работает на очень, очень, очень простой прототип ASP.NET проект MVC 4 с помощью Visual Studio 2012 на Windows сервер 2008 R2:

И вот метод:

Теперь, это, как и другие мои проекты, что использовать Ninject (но не ASP.NET в MVC 3 на .Продажи 4) работа и насколько я знаю, это то, что нужно, чтобы сделать все работы. Так, почему я вдруг получаю нет конструктора без параметров, определенных для данного объекта. исключения?

Обновление

Вот полный файл:

Обновление – пожалуйста, посмотрите на мой ответ на ссылку и объяснение решения этой проблемы

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *