Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Либерти Джесс. Освой самостоятельно С++ за 21 день. - royallib.ru.rtf
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
2.55 Mб
Скачать

День 10 Контрольные вопросы

1. Если вы перегрузили функцию-член, как потом можно будет различить разные варианты функции?

Перегруженными называются функции-члены, которые имеют одно и то же имя, но отличаются по количеству или типу параметров.

2. Какая разница между определением и объявлением?

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

3. Когда вызывается конструктор-копировщик?

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

4. Когда вызывается деструктор?

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

5. Чем отличается конструктор-копировщик от оператора присваивания (=)?

Оператор присваивания работает с существующим объектом, а конструктор-копировщик создает новый временный объект.

6. Что представляет собой указатель this?

Это скрытый параметр в каждой функции-члене, который указывает на сам объект.

7. Как различить перегрузку префиксных и постфиксных операторов приращения?

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

8. Можно ли перегрузить operator+ для переменных типа short int?

Нет, для встроенных типов нельзя перегружать никаких операторов.

9. Допускается ли в C++ перегрузка operator++ таким образом, чтобы он выполнял в классе операцию декремента?

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

10. Как устанавливается тип возврата в объявлениях функций операторов преобразования типов?

Никак. Подобно конструкторам и деструкторам, они не имеют никаких возвращаемых значений.

Упражнения

1. Представьте объявление класса SimpleCircle (простая окружность) с единственной переменой-членом itsRadius (радиус). В классе должны использоваться конструктор и деструктор, заданные по умолчанию, а также метод установки радиуса.

class SimpleCircle

{

   public:

      SimpleCircle();

      ~SimpleCircle();

      void SetRadius(int);

      int GetRadiusO;

   private:

      int itsRadius;

};

2. Используя класс, созданный в упражнении !, с помошью конструктора, заданного по умолчанию, инициализируйте переменную itsRadius значением 5.

SimpleCircle::SimpleCircle():

itsRadius(5);

{ }

3. Добавьте в класс новый конструктор, который присваивает значение своего пара-

метра переменной itsRadius.

SimpleCircle::SimpleCircle(int radius):

itsRadius(radius)

{ }

4. Перегрузите операторы преинкремента и постинкремента для использования в ва-

шем классе SimpleCircle с переменной itsRadius.

const SimpleCircle& SimpleCircle::operator++()

{

   ++(itsRadius);

   return *this;

}

// постфиксный оператор Operator ++(int).

// Выборка, затем инкрементирование

const SimpleCircle SimpleCircle::operator++ (int)

// обьявляем локальный обьект класса SimpleCircle и инициализируем его значением

* this

   SimpleCircle temp(*this);

   ++(itsRadius);

   return temp;

}

5. Измените SimpleCircle таким образом, чтобы сохранять itsRadius в динамической области памяти и фиксировать существующие методы.

class SimpleCircle

{

   public:

      SimpleCircle();

      SimpleCircle(int);

      ~SimpleCircle();

      void SetRadius(int);

      int GetRadius();

      const SimpleCircle& operator++();

      const SimpleCircle operator++(int);

   private:

      int *itsRadius;

};

SimpleCircle::SimpleCircle()

   {itsRadius = new int(5);}

SimpleCircle::SimpleCircle(int radius)

   {itsRadius = new int(radius);}

SimpleCircle::~SimpleCircle()

{

   delete itsRadius;

}

const SimpleCircle& SimpleCircle::operator++()

{

   ++(*itsRadius);

   return <<this;

}

// Постфиксный оператор Operator++(int).

// Выборка, затем инкрементирование

const SimpleCircle SimpleCircle::operator++ (int)

{

   // объявляем локальный объект класса SimpleCircle и инициализируем его значением

   *this

      SimpleCircle temp(<<this);

      ++(*itsRadius);

      return temp;

}

6. Создайте в классе SimpleCircle конструктор-копировщик.

SimpleCircle::SimpleCircle(const SimpleCircle & rhs)

{

   int val = rhs.GetRadius();

   itsRadius = new int(val);

}

7. Перегрузите в классе SimpleCircle оператор присваивания.

SimpleCircle& SimpleCircle::operator=(const SimpleCircle & rhs)

{

   if (this == &rhs)

      return *tnis;

   delete itsRadius;

   itsRadius = new int;

   *itsRadius = rhs.GetRadius();

   return *this;

}

8. Напишите программу, которая создает два объекта класса SimpleCircle. Для создания одного объекта используйте конструктор, заданный по умолчанию, а второму экземпляру при объявлении присвойте значение 9. С каждым из объектов используйте оператор инкремента и выведите полученные значения на печать. Наконец, присвойте значение одного объекта другому объекту и выведите результат на печать.

#include <iostream.h>

class SimpleCircle

{

   public:

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

      SimpleCircle();

      SimpleCircle(int);

      SimpleCircle(const SimpleCircle &);

      ~SimpleCircle() {}

      // методы доступа к данным

      void SetRadius(int);

      int GetRadius() const;

      // операторы

      const SimpleCircle& operator++();

      const SimpleCircle operator++(int);

      SimpleCircle& operator=(const SimpleCircle &):

   private:

      int *itsRadius;

};

SimpleCircle::SimpleCircle()

{itsRadius = new int(5);}

SimpleCircle::SimpleCircle(int radius)

{itsRadius = new int(radius);}

SimpleCircle::SimpleCircle(const SimpleCircle & rh$)

{

   int val = rhs.GetRadius();

   itsRadius = new int(val);

}

SimpleCircle::~SimpleCircle()

{

   delete itsRadius;

}

SimpleCircleS SimpleCircle :operator=(const SimpleCircle & rhs)

{

   if (this == &rhs)

      return <<this;

   *itsRadius = rhs.GetRadius();

   return *this;

}

const SimpleCircle& SimpleCircle::operator++()

{

   ++(*itsRadius);

   return *this;

}

// Постфиксный оператор Operator ++(int).

// Выборка, затем инкрементирование

const SimpleCircle SimpleCircle::operator++ (int)

{

   // объявляем локальный объект класса SimpleCircle и инициализируем его значением

   *this

      SimpleCircle ternp(*this);

      ++(*itsRadius);

      return temp;

}

int SimpleCircle::GetRadius() const

{

   return ~itsRadius;

}

int main()

{

   SimpleCircle CircleOne, CircleTwo(9);

   CircleOne++;

   ++CircleTwo;

   cout << "CircleOne: " << CircleOne.GetRadius() << endl;

   cout << "CircleTwo: " << CircleTwo.GetRadius() << endl;

   CircleOne = CircleTwo;

   cout << "CircleOne: " << CircleOne.GetRadius() << endl:

   cout << "CircleTwo: " << CircleTwo.GetRadius() << endl;

   return 0;

}

9. Жучки: что неправильно в следующем примере использования оператора присваивания?

SQUARE SQUARE::operator=(const SQUARE & rhs)

{

   itsSide - new int;

   *itsSide = rhs.GetSide();

   return *this;

}

Нужно выполнить проверку на равенство объектов rhs и this, в противном случае обращение к оператору а = а приведет к аварийному отказу вашей программы.

10. Жучки: что неправильно в следующем примере использования оператора суммирования?

VeryShort VeryShort::operator+ (const VeryShort& rhs)

{

   itsVai += rhs.GetltsVal();

   return *this;

}

Этот оператор operator+ изменяет значение в одном из операндов, а не создает с помощью суммирования новый объект VeryShort. Правильно написать следующее:

VeryShort VeryShort::operator+ (const VeryShort& rhs)

{

   return VeryShort(itsVal + rhs.GetltsVal());

}