Бьерн Страуструп. Язык программирования С++



Скачать 129.12 Kb.
Дата24.11.2012
Размер129.12 Kb.
ТипДокументы
Бьерн Страуструп. Язык программирования С++
Язык программирования решает две взаимосвязанные задачи:


  • позволяет программисту записать подлежащие выполнению действия и

  • формирует понятия, которыми программист оперирует, размышляя о своей задаче.



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

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

  • вначале необходимо добиться ясного понимания задачи,

  • затем определить ключевые понятия, используемые для ее решения,

  • и, наконец, полученное решение выразить в виде программы.


Однако, детали решения и точные понятия, которые будут использоваться в нем, часто проясняются только после того, как их попытаются выразить в программе. Именно в этом случае большое значение приобретает выбор языка программирования.
Во многих задачах используются понятия, которые трудно представить в программе в виде одного из основных типов или в виде функции без связанных с ней статических данных.
Такое понятие может представлять в программе
класс.
Класс - это тип; он определяет поведение связанных с ним объектов: их создание, обработку и уничтожение.
Кроме этого, класс определяет реализацию объектов в языке, но на начальных стадиях разработки программы это не является и не должно являться главной заботой.
Для написания хорошей программы надо составить такой набор классов, в котором каждый класс четко представляет одно понятие.

В языках Ада, Clu, С++ и подобных им пользователю разрешается определять свои типы, которые трактуются в языке практически так же, как встроенные.
Арифметические типы, подобные типам рациональных и комплексных чисел, являются типичными примерами пользовательских типов:
class complex

{

double re, im;

public:

complex(double r, double i) { re=r; im=i; }

complex(double r) // преобразование float->complex

{ re=r; im=0; }

friend complex operator+(complex, complex);

friend complex operator-(complex, complex); // вычитание

friend complex operator-(complex); // унарный минус

friend complex operator*(complex, complex);

friend complex operator/(complex, complex);

// ...

};
Описание класса (т.е. определяемого пользователем типа) complex задает представление комплексного числа и набор операций с комплексными числами.
Представление является частным (private): re и im доступны только для функций, указанных в описании класса complex. Подобные функции могут быть определены так:
complex operator + ( complex a1, complex a2 )

{

return complex ( a1.re + a2.re, a1.im + a2.im );

}
и использоваться следующим образом:
void f ()

{

complex a = 2.3;

complex b = 1 / a;

complex c = a + b * complex ( 1, 2.3 );

// ...

c = - ( a / b ) + 2;

}
----------------------------------------------------------------------------------------------------------------------------------------------------



Абстрактный тип данных определяется как некий "черный ящик". После своего определения он по сути никак не взаимодействует с программой. Его никак нельзя приспособить для новых целей, не меняя определения. В этом

смысле это негибкое решение.
Пусть, например, нужно определить для графической системы тип shape (фигура). Пока считаем, что в системе могут

быть такие фигуры: окружность (circle), треугольник (triangle) и квадрат (square). Пусть уже есть определения точки и цвета:
class point { /* ... */ };

class color { /* ... */ };
Тип shape можно определить следующим образом:
enum kind { circle, triangle, square };
class shape

{

point center;

color col;

kind k;

// представление фигуры

public:

point where () { return center; }

void move ( point to ) { center = to; draw (); }

void draw ();

void rotate ( int );

// еще некоторые операции

};
"Поле типа" k необходимо для того, чтобы такие операции, как draw () и rotate (), могли определять, с какой фигурой они имеют дело. Функцию draw () можно определить так:
void shape :: draw ()

{
switch ( k )

{

case circle:

// рисование окружности

break;

case triangle:

// рисование треугольника

break;

case square:

// рисование квадрата

break;

}

}
Это не функция, а кошмар. В ней нужно учесть все возможные фигуры, какие только есть. Поэтому она дополняется новыми операторами, как только в системе появляется новая фигура. Плохо то, что после определения новой фигуры нужно проверить и, возможно, изменить все старые операции класса.

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

{

point center;

color col;

// ...

public:

point where () { return center; }

void move ( point to ) { center = to; draw(); }

virtual void draw ();

virtual void rotate ( int );

// ...

};
Те функции, для которых можно определить заявленный интерфейс, но реализация которых (т.е. тело с операторной частью) возможна только для конкретных фигур, отмечены служебным словом virtual (виртуальные).
В Симуле и С++ виртуальность функции означает: "функция может быть определена позднее в классе, производном от данного".
С учетом такого определения класса можно написать общие функции, работающие с фигурами:
void rotate_all ( shape v [], int size, int angle )

// повернуть все элементы массива "v" размера "size"

// на угол равный "angle"

{

int i = 0;

while ( i

{

v [ i ] . rotate ( angle );

i = i + 1;

}

}
Для определения конкретной фигуры следует указать, прежде всего, что это - именно фигура и задать ее особые свойства (включая и виртуальные функции):
class circle : public shape

{

int radius;

public:

void draw () { /* ... */ };

void rotate ( int ) {} // да, пока пустая функция

};
В языке С++ класс circle называется производным по отношению к классу shape, а класс shape называется базовым для класса circle.
Возможна другая терминология, использующая названия "подкласс" и "суперкласс" для классов circle и shape соответственно.
Теперь парадигма программирования формулируется так:
Определите, какой класс вам необходим; предоставьте полный набор операций для каждого класса; общность классов выразите явно с помощью наследования.



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

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

Когда представление типа скрыто, необходимо дать пользователю средства для инициализации переменных этого типа. Простейшее решение - до использования переменной вызывать некоторую функцию для ее инициализации.
Например:
class vector

{

// ...

public:

void init ( init size ); // вызов init () перед первым

// использованием объекта vector

// ...

};
void f ()

{

vector v;

// пока v нельзя использовать

v.init ( 10 );

// теперь можно

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

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

class vector

{

int sz; // число элементов

int * v; // указатель на целые

public:

vector ( int ); // конструктор

int& operator [] ( int index ); // операция индексации

};
Конструктор класса vector можно использовать для контроля над ошибками

и выделения памяти:
vector::vector ( int s )

{

if ( s <= 0 )

error ( "недопустимый размер вектора" );

sz = s;

v = new int [ s ]; // разместить массив из s целых

}

Похожие:

Бьерн Страуструп. Язык программирования С++ iconБьерн Страуструп. Язык программирования С++
Книга Б. Страуструпа "Язык программирования С++" дает описание языка, его ключевых понятий и основных приемов программирования на...
Бьерн Страуструп. Язык программирования С++ iconБуш Ванневар Грейс Хоппер Августа Ада Кинг Бьёрн Страуструп Мартин Фаулер
Древнегреческий учёный и философ
Бьерн Страуструп. Язык программирования С++ iconСоздание автоматизированного руководства пользователя сред программирования mswlogo
Ми программирования (Basic,Pascal), язык Лого. Язык программирования Лого (адаптированный вариант языка искусственного интеллекта...
Бьерн Страуструп. Язык программирования С++ iconИнтегрированная среда программирования Turbo Pascal Язык программирования Pascal
Блеза Паскаля. Первоначально этот язык был создан для обучения программированию. Однако благодаря заложенным в нем большим возможностям...
Бьерн Страуструп. Язык программирования С++ icon16 марта в 17. 45 аудитория 402 главного корпуса Программа курса Основы программирования
Основы программирования. Методика программирования во Flash. Носители кода. Язык Action Script (AS), история, корни. Окно Actions....
Бьерн Страуструп. Язык программирования С++ iconВысокоуровневые методы информатики и программирования тестовые задания
Какой язык программирования представляет собою реализацию концепции процедурного программирования?
Бьерн Страуструп. Язык программирования С++ iconПрограмма курса "Языки и технология программирования (C++)" Доц. А. С. Цветков Введение Предмет "
Алгоритмы, способы описания алгоритмов. Словесный подход. Язык блок-схем. Алгоритмический язык. Алгоритмы и структуры данных. Типы...
Бьерн Страуструп. Язык программирования С++ iconС++. Основы Объектно-ориентированного программирования (ооп)
Первая широко известная реализация принципов ооп – это описание языка С++, Бьярне Страуструп, начало 80-х
Бьерн Страуструп. Язык программирования С++ iconОбзор языков программирования Что такое язык программирования?
Первый вопрос, который обычно задает человек, впервые сталкивающийся с новым языком программирования
Бьерн Страуструп. Язык программирования С++ iconЧто же такое Microsoft Visual FoxPro? Язык программирования, база данных или нечто иное? Немного истории
Ведь язык xBase это значительно более "высокоуровневый", и соответственно более абстрактный язык, нежели традиционный языки программирования,...
Разместите кнопку на своём сайте:
ru.convdocs.org


База данных защищена авторским правом ©ru.convdocs.org 2016
обратиться к администрации
ru.convdocs.org