Читаем Освой самостоятельно С++ за 21 день. полностью

Все, что нам нужно, — это возвратить объект класса Counter таким образом, чтобы ero можно было присвоить другому объекту класса Counter. Как это сделать? Один подход состоит в том, чтобы создать временный объект и возвратить его. Он показан в листинге 10.9.

Листинг 10.8. Возвращение временного объекта

1: // Листинг 10.9.

2: // Возвращение временного объекта

3:

4: int

5: #include

6:

7: class Counter

8: {

9:    public:

10:      Counter;

11:      ~Counter{ }

12:      int GetItsValconst { return itsVal; }

13:      void SetItsVal(int x) { itsVal = x; }

14:      void Increment { ++itsVal; }

15:      Counter operator++ ;

16:

17:   private:

18:      int itsVal;

19:

20: };

21:

22: Counter::Counter:

23: itsVal(0)

24: { }

25:

26: Counter Counter::operator++

27: {

28:    ++itsVal;

29:    Counter temp;

30:    temp.SetItsVal(itsVal);

31:    return temp;

32: }

33:

34: int main

35: {

36:    Counter i;

37:    cout << "The value of i is " << i.GetItsVal << endl;

38:    i.Incrernent;

39:    cout << "The value of i is " << i.GetItsVal << endl;

40:    ++i;

41:    cout << "The value of i is " << i.GetItsVal << endl;

42:    Counter а = ++i;

43:    cout << "The value of a: " << a.GetItsVal;

44:    cout << " and i: " << i.GetItsVal << endl;

45:    return 0;

46: }


Результат:

The value of i is 0

The value of i is 1

The value of i is 2

The value of a: 3 and i: 3


Анализ: В данной версии программы operator++ объявлен в строке 15 таким образом, что может возвращать объекты класса Counter. В строке 29 создается временный объект ternp, и ему присваивается значение текущего объекта Counter. Значение временной переменной возвращается и тут же, в строке 42, присваивается новому объекту а.

Возвращение безымянных временных объектов

В действительности нет необходимости присваивать имя временному объекту, как это было сделано в предыдущем листинге в строке 29. Если в классе Counter есть принимающий значение конструктор, то параметру этого конструктора можно просто присвоить значение возврата оператора инкремента. Эта идея реализована в листинге 10.10.

Листинг 10.10. Возвращение безымянного временного объекта

1: // Листинг 10.10.

2: // Возвращение безымянного временного объекта

3:

4: int

5: #include

6:

7: class Counter

8: {

9:    public:

10:      Counter;

11:      Counter(int val);

12:      ~Counter{ }

13:      int GetItsValconst { return itsVal; }

14:      void SetItsVal(int x) { itsVal = x; }

15:      void Increment { ++itsVal; }

16:      Counter operator++ ;

17:

18:   private:

19:      int itsVal;

20:

21: };

22:

23: Counter::Counter:

24: itsVal(0)

25: { }

26:

27: Counter::Counter(intval):

28: itsVal(val)

29: { }

30:

31: CounterCounter::operator++

32: {

33:    ++itsVal;

34:    return Counter (itsVal);

35: }

36:

37: int main

38: {

39:    Counter i;

40:    cout << "The value of i is" << i.GetItsVal << endl;

41:    i.Increment;

42:    cout << "The value of i is" << i.GetItsVal << endl;

43:    ++i;

44:    cout << "The value of i is" << i.GetItsVal << endl;

45:    Counter a = ++i;

46:    cout << "The value of a: " << a.GetItsVal;

47:    cout << " and i: " << i.GetItsVal << endl;

48:    return 0;

49: }


Результат:

The value of i is 0

The value of i is 1

The value of i is 2

The value of a: 3 and i: 3


Анализ: В строке 11 определен новый конструктор, который принимает значение типа int. Данный конструктор выполняется в строках с 27 по 29. Происходит инициализация переменной itsVal значением, переданным в параметре.

Выполнение оператора инкремента в данной программе упрощено. В строке 33 осуществляется приращение переменной itsVal. Затем в строке 34 создается временный объект класса Counter, которому присваивается значение переменной itsVal. Это значение затем возвращается как результат выполнения оператора инкремента.

Подобное решение выглядит более элегантно, но возникает вопрос, для чего вообще нужно создавать временные объекты. Напомним, что создание и удаление временного объекта в памяти компьютера требует определенных временных затрат. Кроме того, если объект i уже существует и имеет правильное значение, почему бы просто не возвратить его? Реализуем эту идею с помощью указателя this.

Использование указателя this

На прошлом занятии уже рассматривалось использование указателя this. Этот указатель можно передавать в функцию-член оператора инкремента точно так же, как в любую другую функцию-член. Указатель this связан с объектом i и в случае разыменовывания возвращает объект, переменная которого itsVal уже содержит правильное значение. В листинге 10.11 показано возвращение указателя this, что снимает необходимость создания временных объектов.

Листинг 10.11. Возвращение указателя this 

1: // Листинг 10.11.

2: // Возвращение указателя this

3:

4: int

5: #include

6:

7: class Counter

8: {

9:    public:

10:      Counter;

11:      ~Counter{ }

12:      int GetItsValconst { return itsVal; }

13:      void SetItsVal(int x) { itsVal = x; }

Перейти на страницу:

Похожие книги

Сущность технологии СОМ. Библиотека программиста
Сущность технологии СОМ. Библиотека программиста

В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.

Дональд Бокс

Программирование, программы, базы данных / Программирование / Книги по IT