Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Перегрузка операций и дружественные функции.

Поиск

Дружественная функция — это функция, которая не является членом класса, но имеет доступ к членам класса, объявленным в полях private или protected.

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

Одна из причин использования дружественных функций состоит в том, что она нуждается в привилегированном доступе к более чем одному классу. Рассмотрим пример. Требуется написать функцию, которая позволяет сравнивать значения этих классов ruMoney и usMoney.

#include <iostream>

using namespace std;

#include <cstring>

class usMoney;

class ruMoney {

private:

long allcop;

public:

friend int compare(ruMoney rus, usMoney amr, double kurs);

ruMoney(long rub, int cop);

ruMoney() {allcop=0;}

ruMoney(double money);

long getrub() {return static_cast<long>(allcop*0.01);}

int getcop() {return allcop-100*static_cast<long>(0.01*allcop);}

};

ruMoney::ruMoney(long rub, int cop) {

allcop=100*rub+cop;

}

ruMoney::ruMoney(double money) {

allcop=static_cast<long>(100*money);

}

 

class usMoney {

private:

long allcent;

public:

friend int compare(ruMoney rus, usMoney amr, double kurs);

usMoney(long dol, int cent);

usMoney() {allcent=0;}

usMoney(double money);

long getdol() {return static_cast<long>(allcent*0.01);}

int getcent() {return allcent-100*static_cast<long>(0.01*allcent);}

};

 

usMoney:: usMoney (long dol, int cent) {

allcent=100*dol+cent;

}

usMoney:: usMoney (double money) {

allcent=static_cast<long>(100*money);

}

int compare(ruMoney rus, usMoney amr, double kurs) {

if (rus.allcop<amr.allcent*kurs)

return -1;

else if(rus.allcop*kurs==amr.allcent)

return 0;

else

return 1;

}

void main() {

ruMoney a(32,95);

double kurs=29.73;

usMoney b=1.11;

cout<<a.getrub()<<" rub "<<a.getcop()<<" cop\n";

cout<<b.getdol()<<" dol "<<b.getcent()<<" cent\n";

cout<<compare(a,b,kurs)<<endl;

}

 

Вывод этой программы:

32 rub 95 cop

1 dol 11 cent

-1

 

Заметим, что дружественная функция, имеющая доступ к обоим классам, в обоих классах и должна быть определена как дружественная.

Другая причина использования дружественных функций – перегрузка операторов. Язык С++ позволяет перегружать почти все операторы. Это сделано для того, чтобы пользователь класса мог использовать стандартный вид операций, определенный для стандартных типов данных. Логично, например, определить операции +, *, - и т.д. для класса денег. Можно перегружать любые операции (в том числе и операции сравнения, индексирования и т.д.), существующие в С++, за исключением: # ##?: sizeof::.*.

В программе выше использовался стандартный вид вывода для классов ruMoney и usMoney. Логично было бы переопределить функцию вывода так, чтобы она могла выводить объект нашего класса. Это делается с помощью дружественной функции. Наша программа примет вид:

#include <iostream>

using namespace std;

#include <cstring>

class usMoney;

class ruMoney {

private:

long allcop;

public:

friend int compare(ruMoney rus, usMoney amr, double kurs);

friend ostream& operator<<(ostream& out, ruMoney rus);

ruMoney(long rub, int cop);

ruMoney() {allcop=0;}

ruMoney(double money);

long getrub() {return static_cast<long>(allcop*0.01);}

int getcop() {return allcop-100*static_cast<long>(0.01*allcop);}

};

ruMoney::ruMoney(long rub, int cop) {

allcop=100*rub+cop;

}

ruMoney::ruMoney(double money) {

allcop=static_cast<long>(100*money);

}

ostream& operator<<(ostream& out, ruMoney rus) {

return (out<<rus.getrub()<<" rub "<<rus.getcop()<<" cop");

}

 

class usMoney {

private:

long allcent;

public:

friend int compare(ruMoney rus, usMoney amr, double kurs);

friend ostream& operator<<(ostream& out, usMoney amr);

usMoney (long dol, int cent);

usMoney () {allcent=0;}

usMoney (double money);

long getdol() {return static_cast<long>(allcent*0.01);}

int getcent() {return allcent-100*static_cast<long>(0.01*allcent);}

};

usMoney:: usMoney (long dol, int cent) {

allcent=100*dol+cent;

}

usMoney:: usMoney (double money) {

allcent=static_cast<long>(100*money);

}

ostream& operator<<(ostream& out, usMoney amr) {

return (out<<amr.getdol()<<" dol "<<amr.getcent()<<" cent");

}

 

int compare(ruMoney rus, usMoney amr, double kurs) {

if (rus.allcop<amr.allcent*kurs)

return -1;

else if(rus.allcop*kurs==amr.allcent)

return 0;

else

return 1;

}

 

void main() {

ruMoney a(32,95);

double kurs=29.73;

usMoney b=1.11;

cout<<a<<endl<<b<<endl;

cout<<compare(a,b,kurs)<<endl;

}

Вывод ее останется неизменным.

 

Пример:

Переопределим операцию + так, чтобыможно былоскладывать (сцеплять) символьные строки.

#include "stdafx.h"

// DataSet записывает соответствующую информацию массиве объектов

#include <stdio.h>

#include <conio.h>

#include <iostream>

using namespace std;

 

#include <string.h>

const int LEN=80;

struct sString {

char s [LEN];

int len;

};

sString operator + (sString S1, sString S2){

sString TmpS;

if((TmpS.len=S1.len+S2.len)>=LEN){

TmpS.s[0]='\0'; TmpS. len=0;

}

else {

strcpy(TmpS.s, S1.s);

strcat(TmpS.s, S2.s);

}

return TmpS;

}

 

void main(){

setlocale(LC_ALL, "Russian");

sString S1, S2, S3;

strcpy(S1.s, "Пepeгpузкa oпepаций -");

S1.len=strlen(S1.s);

strcpy(S2.s, "классная вещь!");

S2.len=strlen(S2.s);

printf("Были строки:\n %s\n %s\n с длинами %d и %d\n",S1.s, S2.s, S1.len, S2.len);

S3=S1+S2;//гeнepирyeтся код, вызову: operator+(S1, S2);

printf("Пoлучилaсь cтpокa:\n\t%s длиной %d\n", S3.s,S3.len);

_getch();

}

 

Результат:

 

Указатели на функции

#include <iostream>

using namespace std;

 

bool smaller(int a, int b) { return a < b; }

bool greater(int a, int b) { return a > b; }

void sort(int *p, int n, bool(*cmp)(int, int))

{

for (int i= 0; i<n-1; i++)

for (int j = i+1; j < n; j++)

if (cmp(p[i], p[j]))

swap(p[i], p[j]);

}

int main() {

system("color f0");

const int len = 10;

int m[len];

for (size_t i = 0; i < len; i++)

{

m[i] = rand() % 100;

}

sort(m, len, &smaller);

sort(m, len, &greater);

system("pause");

}

 




Поделиться:


Последнее изменение этой страницы: 2016-12-11; просмотров: 262; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.220.85.96 (0.007 с.)