рефераты конспекты курсовые дипломные лекции шпоры

Реферат Курсовая Конспект

Покажчики на члени класу

Покажчики на члени класу - раздел Программирование, Процедурно-орієнтоване (структурне) програмування   Покажчики На Члени Класу Вказують На Нестатичні Поля Або Мето...

 

Покажчики на члени класу вказують на нестатичні поля або методи (включаючи віртуальні) будь-якого об’єкта класу.

 

struct Point

{

int x, y;

void Set(int x0, int y0){x = x0, y = y0;}

};

 

void main()

{

Point a, *pa = &a;

// pint - покажчик на будь-який int член класу Point

int Point::*pint = &Point::x;

// pmf2i - покажчик на будь-яку функцію-член класу Point,

// яка приймає два аргументи типу int і повертає void

void (Point::*pmf2i)(int,int) = &Point::Set;

 

++(a.*pint); // інкремент х

++(pa->*pint); // знову інкремент х

(a.*pmf2i)(1,1); // виклик Set()

(pa->*pmf2i)(2,2); // виклик Set()через pa

}

 

Покажчики на члени класу неявно перетворюються в покажчики на члени похідних класів, якщо це необхідно. Вони не перетворюються неявно в покажчики на void, як звичайні покажчики.

 

 


Лекція 10. Перевантаження операторів

1. Перевантаження операцій

Перевантаження операцій дозволяє розширювати на типи класів значення будь-яких операцій, крім .,.*, ::, sizeof, ? :.

Перевантаження операцій здійснюється шляхом оголошення функції, що складається із ключового слова operator, за яким іде одна зі вбудованих операцій. Перевантаження операцій не може використовувати аргументи за замовчуванням.

2. Унарні оператори

Унарні оператори можуть бути оголошені як нестатичні функції-члени, що не мають аргументів. Тобто @x інтерпретується як x.operator@() для будь-якого оператора @. Унарні оператори можуть бути оголошені як функції, котрі не є членами якого-небудь класу, які мають один аргумент. Цей аргумент є змінною даного класу або посиланням на таку змінну. У цьому випадку @x інтерпретується як operator@(х) для будь-якого оператора @.

 

class X

{

X operator - () const; // унарний мінус

X operator & () const; // обчислення адреси

X operator ^ () const; // помилка: операція ^ бінарна

};

 

class Y

{

friend Y operator - (const Y&); // унарний мінус

friend Y operator & (const Y&); // обчислення адреси

friend Y operator ^ (const Y&); // помилка: операція ^ бінарна

};

3. Бінарні оператори

Бінарні операції можуть бути оголошені як нестатичні функції, що мають один аргумент, тобто x@y інтерпретується як x.operator@(y) для будь-якого оператора @. Бінарні операції можуть бути оголошені як функції, котрі не є членами якого-небудь класу, що мають два аргументи. Тобто для будь-якої операції @ x@y інтерпретується як operator@(х, y).

 

class X

{

X operator- (const X&)const; //бінарний мінус

X operator & (const X&) const; // побітове І

X operator ! (const X&) const; // помилка: операція ! унарна

};

 

class Y

{

friend Y operator - (const Y&, const Y&);

friend Y operator & (const Y&, const Y&);

friend Y operator ! (const Y&, const Y&); // помилка

};

 

4. Операція виклику функції

Операція виклику функції повинна бути оголошена як нестатична функція-член класу. Операція виклику функції дозволяє користувачеві визначати кількість операндів.

 

class X

{

// ...

public:

X(int a, int b, int c);

// ...

void operator () (int i, int j, int k);

 

};

 

X Xamle(1,2,3); // викликається конструктор

Xample(4,5,6); // викликається операція ()

 

Приклад:

 

// function_call.cpp

class Point

{

public:

Point() { _x = _y = 0; }

Point &operator()( int dx, int dy )

{ _x += dx; _y += dy; return *this; }

private:

int _x, _y;

};

 

int main()

{

Point pt;

pt( 3, 2 );

}

5. Операція присвоювання

Операція присвоювання використовується для присвоювання значення одного об’єкта даного класу іншому. Якщо не визначена користувачем, то виконує присвоювання значень полів одного об’єкта даного класу іншому. Повинна бути визначена, коли клас містить поля, які є покажчиками на динамічно виділену пам’ять. Повинна бути визначена як нестатична функція-член класу.

 

class IntStack

{

int *v, size, top;

// ...

public:

IntStack& operator = (const IntStack& from)

{

if(this != &from) // перевірка на from = from

{

delete[] v;

v = new int[size = from.size];

for(register int i=0;i<size;++i)

v[i] = from.v[i];

top = from.top;

}

return *this;// дозволяє виконувати множинне присвоювання

}

 

};

 

// ...

IntStack a(100), b, c;

// ...

c = b = a; // привласнити значення а змінним b і с

 

Приклад:

 

// assignment.cpp

#include <iostream>

 

using namespace std;

 

class Point

{

public:

Point &operator=( Point & ); // Right side is the argument.

int _x, _y;

};

 

// Define assignment operator.

Point &Point::operator=( Point &ptRHS )

{

_x = ptRHS._x;

_y = ptRHS._y;

 

return *this; // Assignment operator returns left side.

}

 

int main()

{

Point pt1, pt2, pt3;

pt1._x = 10;

pt1._y = 20;

pt3 = pt2 = pt1;

cout<<"pt3.x = "<<pt3._x<<" pt3.y = "<<pt3._y<<endl;

 

}

 

6. Операція індексації

Операція індексації повинна бути визначена як нестатична функція-член класу. Операція індексації найчастіше повертає посилання, що дозволяє використовувати її по обидва боки операції присвоювання.

 

class String

{

char* s;

public:

String(char);

String(const char*);

char& operator [](int pos){return s[pos];}

// ...

};

 

String ball = "mitten";

ball[0] = 'k'; // char& допускає присвоювання

 

Приклад:

 

// subscripting.cpp

// compile with: /EHsc

#include <iostream>

 

using namespace std;

class IntVector

{

public:

IntVector( int cElements );

~IntVector() { delete _iElements; }

int& operator[]( int nSubscript );

private:

int *_iElements;

int _iUpperBound;

};

 

// Construct an IntVector.

IntVector::IntVector( int cElements )

{

_iElements = new int[cElements];

_iUpperBound = cElements;

}

 

// Subscript operator for IntVector.

int& IntVector::operator[]( int nSubscript )

{

static int iErr = -1;

 

if( nSubscript >= 0 && nSubscript < _iUpperBound )

return _iElements[nSubscript];

else

{

clog << "Array bounds violation." << endl;

return iErr;

}

}

 

// Test the IntVector class.

int main()

{

IntVector v( 10 );

 

for( int i = 0; i <= 10; ++i )

v[i] = i;

 

v[3] = v[9];

 

for( i = 0; i <= 10; ++i )

cout << "Element: [" << i << "] = " << v[i]

<< endl;

 

return v[0];

}

 

 

7. Операція доступу до члена класу

Операція доступу до члена класу для x->m інтерпретується як (x.operator->()) -> m. Це унарна операція і х – це об’єкт класу, а не покажчик на нього. Операція доступу до члена класу повинна повертати покажчик на об’єкт класу, або об’єкт класу, або посилання на об’єкт класу, для якого ця операція визначена, оскільки оригінальне значення операції -> не губиться, а тільки затримується. Операція доступу до члена класу повинна бути визначена як нестатична функція-член класу.

 

 


Лекція 11. Перевантаження операторів (продовження)

1. Операції інкременту і декременту

Операції інкременту та декременту можуть бути перевантажені як для префіксної, так і для постфіксної форм запису.

Префіксна: оголошується як операція-член класу, що не має аргументів, або як дружня операція, яка має один аргумент, що являє собою посилання на об’єкт даного класу.

Постфіксна: оголошується як операція-член класу, яка має один аргумент типу int, або як дружня операція, що має два аргументи: посилання на об’єкт даного класу й аргумент типу int.

 

class X

{

// ...

public:

X& operator++(); // префіксна форма

X operator++(int); // постфіксна форма

};

 

class Y

{

// ...

public:

friend Y& operator—( Y&); // префіксна форма

friend Y operator—(Y&, int); // постфіксна форма

};

 

Приклад:

 

#include <iostream>

 

using namespace std;

 

// increment_and_decrement.cpp

class Point

{

public:

// Declare prefix and postfix increment operators.

Point& operator++(); // Prefix increment operator.

Point operator++(int); // Postfix increment operator.

 

// Declare prefix and postfix decrement operators.

Point& operator--(); // Prefix decrement operator.

Point operator--(int); // Postfix decrement operator.

 

// Define default constructor.

Point() { _x = _y = 0; }

 

// Define accessor functions.

int x() { return _x; }

int y() { return _y; }

private:

int _x, _y;

};

 

// Define prefix increment operator.

Point& Point::operator++()

{

_x++;

_y++;

return *this;

}

 

// Define postfix increment operator.

Point Point::operator++(int)

{

Point temp = *this;

++*this;

return temp;

}

 

// Define prefix decrement operator.

Point& Point::operator--()

{

_x--;

_y--;

return *this;

}

 

// Define postfix decrement operator.

Point Point::operator--(int)

{

Point temp = *this;

--*this;

return temp;

}

int main()

{

Point p;

cout<<"Before increment:n"<<p.x()<<'t'<<p.y()<<'n';

++p;

cout<<"After increment:n"<<p.x()<<'t'<<p.y()<<'n';

 

return 0;

}

2. Операції new і delete

Операції new і delete надають класу механізм керування власною пам’яттю. Вони повинні мати тип значення, що повертається, void* для new і void для delete. Операції new і delete вимагають параметр типу size_t, визначений у стандартному файлі заголовка <stddef.h>.

 

#include <stddef.h>

class Thing

{

// ...

enum {block = 20};

static Thing* freeList;

public:

// ...

void* operator new (size_t);

void operator delete(void*, size_t);

};

 

void* Thing::operator new(size_t size)

{

Thing* p;

if(!freeList)

{

freeList = p = (Thing*) new char [size * block];

while(p != &freeList[block - 1])

p -> next = p + 1, ++p;

p -> next = 0;

}

p = freeList, freeList = freeList -> next;

return p;

}

 

void Thing::operator delete(void* p, size_t)

{

((Thing*)p) -> next = freeList;

freeList = (Thing*) p;

}

 

Якщо операції new і delete визначені для класу, то вони не можуть бути викликані при виділенні й звільненні пам’яті для масивів об’єктів даного класу.

Операція new може бути перевантажена, щоб приймати додаткові аргументи. Передані аргументи, обмежені дужками, розміщуються при виклику після ключового слова new.

 

class Thing

{

// ...

public:

// ...

/* додати додатковий аргумент buf, що буде використовуватися для виділення пам’яті для Thing за зазначеною адресою. */

void* operator new (size_t size, void* buf);

};

 

// ...

void* Thing::new(size_t size, void* buf)

{

// розмістити Thing за адресою buf

}

 

// ...

char buffer[1000];

Thing* p = new (buffer) Thing;

 

Перевантажена операція new з додатковими аргументами приховує глобальну операцію ::operator new. Тепер при звертанні до new зі звичайним синтаксисом відбудеться помилка.

 

Thing* p = new Thing; // помилка: відсутній аргумент

 

Щоб знову використовувати звичайний синтаксис оператора new, для класу повинна бути передбачена функція-член new, що має тільки один аргумент – size_t size. Вона явно викликає глобальну операцію ::operator new.

 

class Thing

{

// ...

void* operator new (size_t size, void* buf);

void* operator new (size_t size)

{

return ::operator new(size);

}

};

 

3. Операції перетворення

Операції перетворення надають механізм перетворення типів class у вбудовані типи або визначені типи class. Мають форму operator type() {/* ... */}, тобто не мають ні явних аргументів, ні значення, що повертається, отже, не можуть бути перевантажені. Використовуються як доповнення до перетворень в арифметичних виразах, ініціалізаціях, аргументах функцій і значеннях, що повертаються.

 

class String

{

char* s;

public:

// ...

operator const char* () const { return s;}

};

 

void f (const char* s) {/* ... */}

String s;

// ...

f(s); // перетворення: s.operator const char*()

 

У більшості випадків перетворення виконується або за допомогою оператора перетворення, або за допомогою конструктора.

 

class BitString{/* ... */ operator String();};

BitString B;

// ...

f(B); // помилка: перетворення не виконується B.operator String().operator const char*()

 

Операції перетворення успадковуються й можуть бути віртуальними.

 

Приклад:

 

#include <iostream>

 

using namespace std;

 

// spec_conversion_functions.cpp

class Money

{

public:

Money():_amount(0.0){};

void setAmount(double amount)

{

_amount = amount;

}

operator double() { return _amount; }

private:

double _amount;

};

 

int main()

{

Money Account;

Account.setAmount(125.25);

double CashOnHand = Account;

cout << CashOnHand<<'t'<< (double)Account << endl;

}

 

4. Дружні функції

Дружні функції – це функції, які мають доступ до закритої частини класу, членами якого вони не є, і захищеної частини класу, від якого вони не породжені.

Дружні функції можуть бути дружніми більш ніж одному класу. Дружні функції оголошуються всередині оголошення класу, для якого є дружніми. Типи аргументів і тип значення, що повертається, повинні повністю збігатися з оголошеними.

 

class Person

{

int secret; // закрита частина класу

public:

// ...

friend void Spose(Person&) // не член класу

};

 

// ...

void Spose(Person& p)

{

++p.secret; // має доступ до закритої частини класу

}

 

Дружні функції можуть бути членами іншого класу.

class Person

{

// ...

friend void Family::Sibling(); // дружня функція

};

 

Дружні функції можуть бути оголошені для всього класу.

 

class Person

{

// ...

friend class Family; // всі функції-члени класу Family є дружніми

};

 

Дружні функції не транзитивні, тобто друзі друзів класу не є друзями даного класу.

 

class Family

{

friend class DistantRelative;

// ...

};

 

class DistantRelative: public Family

{

void Pry(Person& p)

{

++p.secret; // помилка: DistantRelative не є дружнім класу

// Person, хоча він і породжений від дружнього йому класу

}

};

 

Дружні функції не успадковуються похідними класами.

 

Приклад:

 

// friend_functions.cpp

#include <iostream>

 

using namespace std;

 

class Point

{

friend void ChangePrivate( Point & );

public:

Point( void ) : m_i(0) {}

void PrintPrivate( void ){cout << m_i << endl; }

 

private:

int m_i;

};

 

void ChangePrivate ( Point &i ) { i.m_i++; }

 

int main()

{

Point sPoint;

sPoint.PrintPrivate();

ChangePrivate(sPoint);

sPoint.PrintPrivate();

}

 

 


Лекція 12. Успадкування

1. Похідні класи

Похідні класи надають можливості для створення класу, що є варіацією класу, визначеного раніше. Похідні класи мають доступ до відкритої й захищеної частини базового класу.

– Конец работы –

Эта тема принадлежит разделу:

Процедурно-орієнтоване (структурне) програмування

На сайте allrefs.net читайте: "Процедурно-орієнтоване (структурне) програмування"

Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Покажчики на члени класу

Что будем делать с полученным материалом:

Если этот материал оказался полезным ля Вас, Вы можете сохранить его на свою страничку в социальных сетях:

Все темы данного раздела:

Структура програми
  // Welcome.cpp #include <stdio.h> main() { printf("Hello, world"); return 0; } Перший рядок наведеної

Типи даних
  Type Size char, unsigned char, signed char 1 byte short, unsigned short 2 bytes

Константи
4.1. Цілі знакові константи Десяткові 23, -42, +1991 Мають тип int, якщо значення константи не перевищує максимально припустимого значен

Перерахування
Перерахування дозволяють використати імена замість числових значень. Перерахування можуть задавати ім’я типу. Перерахування можуть бути ініціалізовані певними (цілими) значеннями. Також може бути в

Цикл do - while
do оператор while(вираз);   Цикл do - while являє собою скорочений запис для   label: оператор; if(вираз) goto label;  

Оголошення
Оголошення визначає ім’я функції, тип значення, що повертається, і типи аргументів.   // Два аргументи типу double і повертає значення типу double. double Hypotenuse

Визначення
Визначення функції описує код, виконуваний під час виклику функції. Визначення функції може бути оголошено inline для оптимізації дуже маленьких функцій. Це оголошення не гарантує, що функція, огол

Покажчики
Покажчики – це змінні, які містять адресу іншої змінної або функції. Покажчики оголошуються за допомогою символу *.   int i, *pi = &i; // покажчик на int int *pp

Посилання
Посилання – це друге ім’я для іншої змінної. Посилання оголошуються за допомогою символу &. При оголошенні посилання повинні бути ініціалізовані (посилання може бути ініціалізоване лише один ра

Вектори
Вектори – це безперервні блоки пам’яті, що зберігають множину елементів того самого типу. Вони оголошуються за допомогою зазначення кількості елементів, що повинно бути позитивним цілим константним

Структури
Структури – це набір зв’язаної інформації, можливо, різних типів, об’єднаний в один об’єкт. Структури можуть мати ім’я, що у цьому випадку буде ім’ям типу.   struct Call

Конструктори
Конструктори ініціалізують об’єкт класу з необов’язковим списком аргументів. Аргументи, якщо вони використовуються, можуть мати значення за замовчуванням. Конструктори автоматично викликаю

Конструктори за замовчуванням
Конструктори за замовчуванням не мають аргументів (або всі аргументи мають значення за замовчуванням). Конструктор за замовчуванням потрібен, коли створюється масив об’єктів даного класу з використ

Деструктори
Деструктори виконують усі необхідні дії перед знищенням об’єкта. Деструктори автоматично викликаються компілятором: 1) при виході з області видимості; 2) при створенні тимчасових

Оголошення
Оголошення похідного класу вводить новий тип. Оголошення похідного класу встановлює обмеження доступу private, protected або public для членів свого базового класу. За замовчуванням встановлюється

Оголошення доступу
Оголошення доступу дає можливість знову зробити захищеними або відкритими захищені і відкриті члени закритого базового класу в похідному класі. Дозволяють зробити знову відкритими відкриті члени за

Стани помилки
Стани помилки підтримуються кожним із потоків. Стани помилки зберігаються як набір бітів: eofbit, failbit і badbit. Множинні стани одержуються за допомогою операції побітового АБО. int eof

Потокове виведення
Потокове виведення досягається при використанні змінних класів ostream або istream. Потокове виведення може застосовуватися з одним із визначених вихідних потоків або з вихідним потоком, що був виз

Потокове введення
Потокове введення досягається при використанні змінної класу istream або iostream. Може застосовуватися з визначеним вхідним потоком cin чи із вхідним потоком, визначеним користувачем.

Файлове виведення
Файлове виведення досягається при зв’язуванні вихідного потоку з файлом за допомогою змінної класу ofstream або fstream. Ці класи визначені у файлі заголовка fstream.h. Файлове виведення може викор

Файлове введення
Файлове введення досягається при зв’язуванні вхідного потоку з файлом за допомогою змінної класу ifstream або fstream. Ці класи визначені у файлі заголовка fstream.h. Файлове введення може використ

Стани форматування
Стани форматування управляють появою чисел при виконанні операції вставки у вихідний потік і форматуванням при виконанні операції зчитування із вхідного потоку. Стани форматування встановлюються за

Установка ширини поля
int width(int minimum); – установлює мінімальну ширину поля для даного розміру й повертає попередню ширину поля. Нуль означає відсутність мінімуму. Коли при вставці в потік або витягу з по

Установка системи числення
ios& dec(ios&); ios& oct(ios&); ios hex(ios&); ios& setbase(int); – змінює систему числення, використовувану для подання цілих чисел при

Шаблони
Шаблони розширюють поняття функції й класу, надаючи можливості їхньої параметризації, тобто оголошення функцій і класів у термінах «будь-якого типу». 2. Шаблони функцій

Хотите получать на электронную почту самые свежие новости?
Education Insider Sample
Подпишитесь на Нашу рассылку
Наша политика приватности обеспечивает 100% безопасность и анонимность Ваших E-Mail
Реклама
Соответствующий теме материал
  • Похожее
  • Популярное
  • Облако тегов
  • Здесь
  • Временно
  • Пусто
Теги