이번에는 함수 호출 연산자 중복 정의와 함수 개체를 알아보기로 해요.
C++언어에서는 함수 호출 연산자를 중복정의 할 수 있습니다. 함수 호출 연산자의 연산 기호는 ( ) 입니다. 따라서 함수 호출 연산자를 중복 정의할 때 메서드 이름은 operator()입니다. 메서드 뒤에 입력 매개 변수 리스트를 열거하는 ()에는 개발자가 개수와 형식을 결정하고 반환 형식도 개발자가 정합니다.
[반환형식] operator() ([입력 매개 변수 리스트]);
그리고 함수 호출 연산자를 중복 정의한 형식의 개체를 함수 개체라고 부릅니다. 함수 개체는 형식 내부에 함수 호출 연산자를 중복 정의하고 있어서 마치 함수처럼 호출하여 사용할 수 있습니다.
먼저 간단하게 함수 호출 연산자 중복 정의를 사용하여 함수 개체를 함수처럼 사용하는 예를 보여드를게요.
//함수 호출 연산자 중복 정의
#include <iostream>
using namespace std;
class FunClass
{
public:
int operator()(int a,int b)//함수 호출 연산자 중복 정의
{
cout<<"테스트"<<endl;
return a*b;
}
};
int main()
{
FunClass fc;//함수 개체
cout<<fc(3,4)<<endl;//함수 개체를 함수처럼 사용
return 0;
}
▷ 실행 결과
테스트
12
보통 함수 개체는 메서드를 구현하는 곳에서 모든 알고리즘을 정의하지 못하고 일부를 호출하는 곳에서 정의한 알고리즘을 이용할 때 사용합니다. 예를 들어 회원을 보관하는 배열을 구현하면서 검색 기능을 구현할 때 호출하는 곳에서 검색 기능을 구현한 함수 개체를 입력 인자로 받아 이를 이용하는 것이죠. 또한 배열에 보관한 회원 정보를 출력하는 알고리즘을 호출하는 곳에서 함수 개체로 전달받아 이를 이용하여 출력하게 할 수도 있겠죠. 마찬가지로 배열에 보관한 회원 정보를 정렬할 때 비교 알고리즘을 함수 개체를 입력 인자로 전달받아 이용할 수도 있을 거예요.
다음처럼 배열에서는 함수 호출 연산자를 중복 정의한 알고리즘을 추상화합니다.
#define interface struct
interface IEqual
{
virtual bool operator()(Member *member)=0;
};
그리고 배열의 검색 기능에서는 함수 개체를 입력 인자로 받아 조건에 맞는 것을 구현하죠.
Member *MemberCollection::FindIf(IEqual &ie)
{
for(int i=0;i<usage;i++)
{
if(ie(base[i]))
{
return base[i];
}
}
return 0;
}
사용하는 곳에서는 검색에 필요한 알고리즘을 구체적으로 구현합니다.
class EqualerNum:public IEqual
{
int num;
public:
EqualerNum(int num)
{
this->num = num;
}
virtual bool operator()(Member *member)
{
return num == member->GetNum();
}
};
그리고 배열의 검색 요청 시에 구체적으로 구현한 함수 개체를 입력 인자로 전달하여 원하는 것을 찾습니다.
MemberCollection mc(10);
...중략...
EqualerNum en(3);
Member *member = mc.FindIf(en);
if(member==0)
{
cout<<"검색 실패"<<endl;
}
else
{
cout<<"번호:"<<member->GetNum()<<" 이름:"<<member->GetName()<<endl;
}
다음은 함수 개체를 이용하여 회원 컬렉션을 정의하고 이를 이용하는 예제 코드입니다.
//Member.h
#pragma once
#include <iostream>
#include <string>
using namespace std;
class Member
{
const int num;
string name;
public:
Member(int num,string name);
int GetNum()const; //회원 번호 접근자
string GetName()const; //회원 이름 접근자
};
//Member.cpp
#include "Member.h"
Member::Member(int num,string name):num(num)
{
this->name = name;
}
int Member::GetNum()const
{
return num;
}
string Member::GetName()const
{
return name;
}
//MemberCollection.h
#pragma once
#include "Member.h"
#define interface struct
interface IEqual//조건 알고리즘 추상화
{
virtual bool operator()(Member *member)=0;
};
interface IDoSome //회원에 관한 알고리즘 추상화
{
virtual void operator() (Member *member)=0;
};
interface ICompare//회원 비교 알고리즘 추상화
{
virtual int operator()(Member *m1,Member *m2)=0;
};
class MemberCollection
{
Member **base;
const int max_member;
int usage;
public:
MemberCollection(int max);
~MemberCollection(void);
void PushBack(Member *member);//순차 보관
Member *FindIf(IEqual &ie); //조건에 맞는 개체 탐색
void ListMember(IDoSome &iv); //전체 회원 데이터에 알고리즘 적용
void Sort(ICompare &ic); //검색 알고리즘 이용하여 정렬
};
//MemberCollection.cpp
#include "MemberCollection.h"
MemberCollection::MemberCollection(int max):max_member(max)
{
base = 0;
if(max)
{
base = new Member *[max];
}
usage = 0;
}
MemberCollection::~MemberCollection(void)
{
if(base)
{
delete[] base;
}
}
void MemberCollection::PushBack(Member *member)
{
if(usage<max_member)
{
base[usage] = member;
usage++;
}
}
Member *MemberCollection::FindIf(IEqual &ie)
{
for(int i=0;i<usage;i++)
{
if(ie(base[i])) //조건 알고리즘을 사용
{
return base[i];
}
}
return 0;
}
void MemberCollection::ListMember(IDoSome &iv)
{
for(int i=0;i<usage;i++)
{
iv(base[i]);//회원에 관한 알고리즘 사용
}
}
void MemberCollection::Sort(ICompare &ic)
{
for(int i=usage;i>1;i--)
{
for(int j=1;j<i;j++)
{
if(ic(base[j-1],base[j])>0) //비교 알고리즘 사용
{
Member *temp = base[j-1];
base[j-1] = base[j];
base[j]=temp;
}
}
}
}
//Program.cpp
#include "MemberCollection.h"
class EqualerNum:public IEqual //번호로 비교 알고리즘
{
int num;
public:
EqualerNum(int num)
{
this->num = num;
}
virtual bool operator()(Member *member)
{
return num == member->GetNum();
}
};
class ViewMember:public IDoSome//회원 출력 알고리즘
{
public:
virtual void operator() (Member *member)
{
cout<<"번호:"<<member->GetNum()<<" 이름:"<<member->GetName()<<endl;
}
};
class ViewMember2:public IDoSome//회원 출력 알고리즘2
{
public:
virtual void operator() (Member *member)
{
cout<<"이름:"<<member->GetName()<<" 번호:"<<member->GetNum()<<endl;
}
};
class Dispose:public IDoSome////회원에 관한 소멸 알고리즘
{
public:
virtual void operator() (Member *member)
{
delete member;
}
};
class CompareByNum:public ICompare//번호로 비교 알고리즘
{
public:
virtual int operator()(Member *m1,Member *m2)
{
return m1->GetNum()-m2->GetNum();
}
};
class CompareByName:public ICompare//이름으로 비교 알고리즘
{
public:
virtual int operator()(Member *m1,Member *m2)
{
string s1 = m1->GetName();
string s2 = m2->GetName();
return s1.compare(s2);
}
};
int main()
{
MemberCollection mc(10);
mc.PushBack(new Member(5,"이순신"));
mc.PushBack(new Member(3,"홍길동"));
mc.PushBack(new Member(1,"강감찬"));
EqualerNum en(3);//번호로 검색 알고리즘 함수 개체
Member *member = mc.FindIf(en);//입력 인자로 함수 개체 전달
if(member==0)
{
cout<<"검색 실패"<<endl;
}
else
{
cout<<"번호:"<<member->GetNum()<<" 이름:"<<member->GetName()<<endl;
}
cout<<"전체 출력1"<<endl;
ViewMember vm;//회원 출력 알고리즘 함수 개체
mc.ListMember(vm);//입력 인자로 함수 개체 전달
cout<<"전체 출력2"<<endl;
ViewMember2 vm2;//회원 출력 알고리즘2 함수 개체
mc.ListMember(vm2);//입력 인자로 함수 개체 전달
cout<<"번호로 정렬 후 출력"<<endl;
CompareByNum cbnum;//번호로 비교 알고리즘 함수 개체
mc.Sort(cbnum);//입력 인자로 함수 개체 전달
mc.ListMember(vm);//입력 인자로 함수 개체 전달
cout<<"이름으로 정렬 후 출력"<<endl;
CompareByName cbname;//이름으로 비교 알고리즘 함수 개체
mc.Sort(cbname);//입력 인자로 함수 개체 전달
mc.ListMember(vm2);//입력 인자로 함수 개체 전달
Dispose dispose;//소멸 알고리즘 함수 개체
mc.ListMember(dispose);//입력 인자로 함수 개체 전달
return 0;
}
▷ 실행 결과
번호:3 이름:홍길동
전체 출력1
번호:5 이름:이순신
번호:3 이름:홍길동
번호:1 이름:강감찬
전체 출력2
이름:이순신 번호:5
이름:홍길동 번호:3
이름:강감찬 번호:1
번호로 정렬 후 출력
번호:1 이름:강감찬
번호:3 이름:홍길동
번호:5 이름:이순신
이름으로 정렬 후 출력
이름:강감찬 번호:1
이름:이순신 번호:5
이름:홍길동 번호:3
'언어 자료구조 알고리즘 > 디딤돌 C++' 카테고리의 다른 글
[C++] 57. 예외 처리(C언어 , C++, C# 예외처리 비교) (0) | 2016.05.01 |
---|---|
[C++] 56. string 클래스 흉내내기2 (0) | 2016.04.25 |
[C++] 55. string 클래스 흉내내기1 (0) | 2016.04.25 |
[C++] 54. 개체 출력자 (0) | 2016.04.25 |
[C++] 53. iostream 흉내내기 (0) | 2016.04.25 |
[C++] 51. 묵시적 형 변환 연산자 중복 정의 (0) | 2016.04.25 |
[C++] 50. 인덱스 연산자 중복 정의 (0) | 2016.04.25 |
[C++] 49. 대입 연산자 중복 정의 (0) | 2016.04.25 |
[C++] 48. 증감 연산자 중복 정의 (0) | 2016.04.25 |
[C++] 47. 클래스에 연산자 중복 정의 (0) | 2016.04.25 |