Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

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

Управление доступом

Понятие структуры расширено в С++ так, что появилась возможность вводить закрытые (private) и открытые (public) члены. Это касается как членов данных, так и функций-членов структуры.

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

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

 

struct primer{

public:

int a; //public member

double b(int); //public member

private:

int c; //private member

double d(int); //private member

};

double primer::b(int p)

{

a=7; //ok, can access all members

b(3); //ok

c=2; //ok

return d(1); //ok

}

 

double primer::d(int p)

{

a=7; //ok, can access all members

b(3); //ok

c=2; //ok

return d(1); //ok

}

 

double use(int p)

{

primer pr;

 

pr.a=7; //ok, public member

pr.b(3); //ok, public member

// pr.c=2; //error: cannot access private member

// return pr.d(1);//error: cannot access private member

return 1;

}

Переменная primer::c может быть изменена с помощью вызова функции primer::b(), но не непосредственно.

Полезно рассматривать закрытую часть, как код, доступный только разработчику, а открытую часть – как описание интерфейса, который используется клиентами. Разработчик может изменить закрытую часть, и это не повлияет на правильность использования структуры клиентом. То есть при изменении закрытой части структуры не нужно переписывать код, который использует эту структуру (хотя может потребоваться его перекомпиляция).

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

Другое преимущество – локализация ошибок. Неправильное значение закрытого члена данных может быть вызвано только неверным кодом функций-членов.

 

Классы являются формой структуры, у которой право доступа по умолчанию закрытое. Таким образом, struct и class взаимозаменяемы при условии надлежащего определения прав доступа.

class a{

int b;//private

}


Использование функций типа reset() или init() для инициализации объектов класса неэлегантно и подвержено ошибкам. Программист может забыть проинициализировать объект или сделать это дважды. Лучшим подходом будет предоставление программисту возможности объявить функцию, имеющую явное назначение – инициализация объектов. Ввиду того, что такая функция создает (конструирует) значения данного типа, она называется конструктором. Конструктор распознается по имени, которое совпадает с именем класса.

Конструкторы – это специальные функции-члены, которые определяют, как инициализируются объекты.

Бывает удобно иметь несколько способов инициализации объекта класса. Этого можно добиться, введя несколько конструкторов.

 

class stack3

{

public:

stack3(); //конструктор по умолчанию

stack3(char);//stack that contains 1 element

void push(char c);

char pop();

bool is_empty()const;

bool is_full()const;

private:

enum{ max_len=100};

int top;

char s[max_len];

 

};

 

Конструктор выполняется в момент создания объекта.

void use_stack3()

{

stack3 s; //выполняется конструктор по умолчанию

stack3 s1(’d’);//выполняется конструктор с одним аргументом

stack3 *ps=new stack3();//выполняется конструктор по умолч.

stack3 *ps1=new stack3(’d’);//выполн. конструктор c 1 арг.

delete ps;

delete ps1;

}

 

Определение конструктора

stack3::stack3():top(0){}

 

stack3::stack3(char c)//stack that contains 1 element

:top(1)

{

s[0]=c;

}

В определении конструктора используется новый для вас синтаксис. Между символом «:» и открывающей фигурной скобкой ({) находится ряд инициализаторов конструктора (constructor initializers), в данном случае 1 инициализатор. Инициализаторы конструктора велят компилятору инициализировать заданные члены значениями, указанными в соответствующих круглых скобках. В частности, top устанавливается равным 0. Второй конструктор иниц.1 и выполняет присваивание.

Чтобы понять, как создаются и инициализируются объекты, важно уяснить работу инициализаторов конструктора. При создании нового объекта класса последовательно выполняются следующие действия.

 

1. C++ - среда выделяет память для хранения объекта.

2. C++ - среда инициализирует объект в соответствии со списком инициализации конструктора.

3. C++ - среда выполняет тело конструктора.

 

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

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

 

Пример с 2 инициализаторами конструктора.

 

class complex{

complex(double real, double imag);

complex(double real);

};

 

complex::complex(double real, double imag)

{re=real; im=imag;}

complex::complex(double real)

{re=real; im=0;}

Использование:

complex c3(2,3); //инициализация

 

Конструктор не имеет возвращаемого значения (даже void).

 

Если мы не определим ни одного конструктора, компилятор синтезирует его за нас. Синтезированный конструктор вызывает конструкторы по умолчанию для всех членов данных-объектов. Те члены данных, которые имеют встроенный тип, не инициализируются (содержат мусор).

<== предыдущая лекция | следующая лекция ==>
Структуры. Унарные операторы new и delete служат для управления свободной памятью | Функции-члены типа static и const
Поделиться с друзьями:


Дата добавления: 2014-01-11; Просмотров: 431; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.012 сек.