132.79K
Category: programmingprogramming

Некоторые особенности конструкторов

1.

Некоторые
особенности
конструкторов

2.

Отличие конструктора копирования о
т конструктора преобразования
Входной параметр конструктора копиров
ания имеет тип, описываемый данным кл
ассом.
Если описывается класс Х, то его конструкт
ор копирования может иметь один из сле
дующих прототипов:
Х(Х&);
Х(const Х&);

3.

Следующие инструкции вызовут конструктор
копирования класса MyClass:
MyClass x = y; // y явно инициализирует x
func1(y);
// y передается в качестве пар
аметра (по значению)
y = func2(); // y получает возвращаемый
объект.

4.

В двух первых случаях конструктору коп
ирования передается ссылка на y. В п
оследнем случае конструктору копиров
ания передается ссылка на объект, возв
ращаемый функцией func2().

5.

Запрет копирования объектов
Возможны ситуации, когда операция копиров
ания объекта не имеет смысла и должна быт
ь запрещена
Объект должен существовать в единственном экзем
пляре внутри приложения, например, «клавиатура»
Для запрещения копирования объекта,
конструктор копирования объявляется в
закрытой (private) области класса
Реализацию данного конструктора можно не писать

6.

Пример
class CFile
{
public:
// …
private:
CFile(Cfile const&);
// …
};

7.

Наследование,
множественное
наследование

8.

Наследование
Объект производного класса обладает всеми
методами и атрибутами базового. Помимо ни
х, в него можно добавить новые.
Производный класс может быть базовым для
какого-то другого класса, т.е. иерархия классо
в может быть сколь угодно глубокой.

9.

Наследование. Пример
class A
{
int
m_i;
float m_f;
};
class B: A
{
double m_d;
};
class C: B
{
long m_l;
};
A
B
int m_i;
float m_f;
int m_i;
float m_f;
double m_d;
int m_i;
float m_f;
C double m_d;
long m_l;

10.

Наследование. Пример
class A
{
int
m_i;
float m_f;
MethodA();
};
class B: A
{
double m_d;
};
class C: B
{
long m_l;
};
B b;
b.MethodA();

11.

Множественное наследование
class A
{
int m_i;
};
class B
{
double m_d;
};
A
B
int m_i;
double m_d;
C
int m_i;
double m_d;
float m_f;
class C: A, B
{
float m_f;
};

12.

Модификаторы доступа
public
Поле/метод с таким модификатором доступн
о отовсюду (из самого класса, из его потомко
в, из глобальных функций).
protected
Доступно из самого класса и производных от
него, но недоступно извне.
private
Доступно только из самого класса.

13.

Модификаторы доступа
При наследовании также указывается м
одификатор доступа. В соответствии с н
им в производном классе изменяются у
ровни доступа.
Для класса можно указать дружественн
ые классы и функции (friend). Они будут
иметь доступ ко всем полям класса.

14.

Модификаторы доступа.
Пример.
class A
{
private:
int m_priv;
protected:
int m_prot;
public:
int m_pub;
};
class B: public A;
class C: protected A;
class D: private A;
m_priv доступен только из
класса A;
m_prot доступен из классов A
и производных от него (в B,C
это поле остается protected, в
D становится private);
m_pub доступен из классов A,
в производных от него, а
также извне. В классе B это
поле остается public, в классе
C становится protected, в
классе D – private.

15.

Полиморфизм

16.

Статический полиморфизм в С++
определение в одном классе нескольких методов с одним и тем
же именем, но разными типами и количеством аргументов
// определение класса комплексных чисел:
void main ()
class Complex
{
{
Complex c1,c2;
long x;
public:
c1 + c2;
int real; // вещественная часть c2 + x;
int imaginary; // мнимая часть }
// прибавить комплексное число:
Complex operator+(const Complex x) const;
// прибавить целое число:
Complex operator+(long x) const;
};

17.

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

18.

Виртуальные функции. Пример.
class Shape
{
int cx, cy;
virtual void print();
};
class Circle: Shape
{
int r;
virtual void print();
};
class Rect: Shape
{
int w,h;
virtual void print();
};
Пусть есть массив
Shape* shapes[];
Несмотря на то, что тип элементов
массива – Shape*, т.е. указатель на
объект типа Shape, реально по
указателю может лежать любой
объект производного типа.
Если мы напишем такой цикл, то
вызываться будет функция print
того типа, который на самом деле
находится по адресу shapes[i]:
for(int i = 0; i < N; i++)
{
shapes[i]->print();
}

19.

Дружественные
функции и классы

20.

Дружественные функции и классы
Иногда желательно дать функциям, не являющимися элементам
и, доступ к личной части объекта класса.
Для этого в декларации класса помещается декларация функции,
перед которой стоит ключевое слово friend.
Особенности дружественных функций:
дружественная функция может быть другом двух и более клас
сов;
декларация friend - это только декларация, вводящая имя функ
ции в самую широкую область действия в программе; деклара
цию можно поместить как в private-, так и в public- части описан
ия класса – компилятору это безразлично;
дружественная функция лишь имеет права доступа к приватно
й части объекта: если она не является полноправной функцие
й-элементом, то у нее нет и указателя this.
Иными словами, встретив ключевое слово friend, компилятор про
сто отключает проверку прав доступа.
Замечание: друзья не наследуются

21.

Дружественные функции.Пример
class monstr
{
int health, ammo;
char *name;
public:
friend int steal_ammo(monstr &);
friend void hero::kill(monstr &);
int get_health(){return health;}
int get_ammo(){return ammo;}
};
class hero {
public:
void kill(monstr &);
};
©Павловская Т.А. (СПбГУ ИТМО)

22.

Дружественные функции и классы
Дружественная функция объявляется внутри
класса, к элементам которого ей нужен досту
п, с ключевым словом friend.
Дружественная функция может быть обычно
й функцией или методом другого ранее опре
деленного класса.
©Павловская Т.А. (СПбГУ ИТМО)

23.

Дружественные функции.Пример
int steal_ammo(monstr &M)
{
return --M.ammo;
}
void hero::kill(monstr &M)
{
M.health = 0; M.ammo = 0;
}
©Павловская Т.А. (СПбГУ ИТМО)

24.

Дружественные классы - пример
class hero{
...
friend class patriarch;
}
class patriarch
{
...
void f1();
void f2();
}
©Павловская Т.А. (СПбГУ ИТМО)

25.

Пример 2
class x
{ ...
void f();
};
class y
{ ...
friend void x::f(); //функция f() из класса x объявляется д
ружественной
};
class x
{ ...
friend class y; //все функции класса y являются дружест
венными классу x
}
English     Русский Rules