Статья : Присваивание и Инициализация 


Полнотекстовый поиск по базе:

Главная >> Статья >> Информатика, программирование


Присваивание и Инициализация




Присваивание и Инициализация

Рассмотрим очень простой класс строк string:

struct string {

char* p;

int size; // размер вектора, на который указывает p

string(int sz) { p = new char[size=sz]; }

~string() { delete p; }

};

Строка - это структура данных, состоящая из вектора символов и длины этого вектора. Вектор создается конструктором и уничтожается деструктором. Однако это может привести к неприятностям.

Например:

void f()

{

string s1(10);

string s2(20);

s1 = s2;

}

будет размещать два вектора символов, а присваивание s1=s2 будет портить указатель на один из них и дублировать другой. На выходе из f() для s1 и s2 будет вызываться деструктор и уничтожать один и тот же вектор с непредсказуемо разрушительными последствиями. Решение этой проблемы состоит в том, чтобы соответствующим образом определить присваивание объектов типа string:

struct string {

char* p;

int size; // размер вектора, на который указывает p

string(int sz) { p = new char[size=sz]; }

~string() { delete p; }

void operator=(string&)

};

void string::operator=(string& a)

{

if (this == &a) return; // остерегаться s=s;

delete p;

p=new char[size=a.size];

strcpy(p,a.p);

}

Это определение string гарантирует, и что предыдущий пример будет работать как предполагалось. Однако небольшое изменение f() приведет к появлению той же проблемы в новом облике:

void f()

{

string s1(10);

s2 = s1;

}

Теперь создается только одна строка, а уничтожается две. К неинициализированному объекту определенная пользователем операция присваивания не применяется. Беглый взгляд на string::operator=() объясняет, почему было неразумно так делать: указатель p будет содержать неопределенное и совершенно случайное значение. Часто операция присваивания полагается на то, что ее аргументы инициализированы. Для такой инициализации, как здесь, это не так по определению. Следовательно, нужно определить похожую, но другую, функцию, чтобы обрабатывать инициализацию:

struct string {

char* p;

int size; // размер вектора, на который указывает p

string(int sz) { p = new char[size=sz]; }

~string() { delete p; }

void operator=(string&)

string(string&);

};

void string::string(string& a)

{

p=new char[size=a.size];

strcpy(p,a.p);

}

Для типа X инициализацию тем же типом X обрабатывает конструктор X(X&). Нельзя не подчеркнуть еще раз, что присваивание и инициализация - разные действия. Это особенно существенно при описании деструктора. Если класс X имеет конструктор, выполняющий нетривиальную работу вроде освобождения памяти, то скорее всего потребуется полный комплект функций, чтобы полностью избежать побитового копирования объектов:

class X {

// ...

X(something); // конструктор: создает объект

X(&X); // конструктор: копирует в инициализации

operator=(X&); // присваивание: чистит и копирует

~X(); // деструктор: чистит

};

Есть еще два случая, когда объект копируется: как параметр функции и как возвращаемое значение. Когда передается параметр, инициализируется неинициализированная до этого переменная - формальный параметр. Семантика идентична семантике инициализации. То же самое происходит при возврате из функции, хотя это менее очевидно. В обоих случаях будет применен X(X&), если он определен:

string g(string arg)

{

return arg;

}

main()

{

string s = "asdf";

s = g(s);

}

Ясно, что после вызова g() значение s обязано быть "asdf". Копирование значения s в параметр arg сложности не представляет: для этого надо взывать string(string&). Для взятия копии этого значения из g() требуется еще один вызов string(string&); на этот раз инициализируемой является временная переменная, которая затем присваивается s. Такие переменные, естественно, уничтожаются как положено с помощью string::~string() при первой возможности.

Список литературы

Для подготовки данной работы были использованы материалы с сайта http://www.realcoding.net

Похожие работы:

  • Язык С

    Реферат >> Информатика, программирование
    ... своему результату, инициализации автоматических перемен- ных являются сокращенной записью операторов присваивания. Какую ... . мы обычно используем явные присваивания, потому что инициализация в описаниях менее заметна. Автоматические ...
  • Язык С

    Дипломная работа >> Информатика, программирование
    ... своему результату, инициализации автоматических переменных являются сокращенной записью операторов присваивания. Какую форму ... . мы обычно используем явные присваивания, потому что инициализация в описаниях менее заметна. Автоматические ...
  • Turbo C++ Programer`s guide

    Реферат >> Информатика, программирование
    ... списке инициализации. class X (* int a, b; public: X(int i, j) : a(i), b(a+j) (**) *); В пределах класса объявление X x(1,1) приведет к присваиванию ... функции. Illegal initialization Недопустимая инициализация Инициализация может выполняться либо выражением ...
  • Лекции по C++

    Реферат >> Информатика, программирование
    ... или присваива­нии начальных значений, посредством операторов внутри блока. Если нет инициализации, то ... прост: требуется операция при­сваивания и строковая константа. Инициализация строки Общий метод инициализации строки: char ...
  • Распределенные алгоритмы

    Реферат >> Информатика, программирование
    ... в действии. Т.к. w = inp[B+I] из (8), присваивание Exp := I + 1 сохраняет (12). Теперь ... также оптимальный путь. _____________________________________________________________________ begin (* Инициализация S =  и D = -дистанция *) S:=0; forall u,v do ...
  • Основы алгоритмического языка С++

    Реферат >> Информатика, программирование
    ... присваивании начальных значений, посредством операторов внутри блока. Если нет инициализации ... объекта. Поэтому вышеприведенная инициализация эквивалентна следующей: int ... присваивания и строковая константа. Инициализация строки Общий метод инициализации ...
  • Объективное программирование

    Реферат >> Информатика, программирование
    ... Си++ Эквивалент в "классическом" Си ------------------------ -----------------------------//--------------- Инициализация константой -----------------int &a = 5; int a, *pa ... нельзя. Их инициализация осуществляется либо явным присваиванием (копированием) ...
  • Основные понятия алгоритмического языка

    Реферат >> Информатика, программирование
    ... ( 0, 2.1, 4, 5.65, 6.1, 6.7, 7.2, 8, 8.7, 9.3 ); При инициализации двумерных массивов значения компонент каждого ... и константам множественного типа применимы операции присваивания(:=), объединения(+), пересечения(*) и вычитания(-): ['A','B'] + ['A','D'] ...
  • Модули и объекты в языке Турбо Паскаль 7.0

    Реферат >> Информатика, программирование
    ... Implementation Секция реализации Секция инициализации Рис. 1. Структура модуля ... необходимые действия по инициализации (например, по присваиванию начальных значений переменным ... действия можно выполнить в секции инициализации модуля. Эта секция начинается словом ...
  • Язык Java

    Реферат >> Информатика, программирование
    ... минус) -= Вычитание с присваиванием * Умножение * = Умножение с присваиванием / Деление /= Деление с присваиванием % деление по модулю ... оператора while: [ инициализация; ] while ( завершение ) { тело; [итерация;] } Инициализация и итерация необязательны. ...