C++이 어려워지므로, 수업시간에 공부한 예제 중심으로 설명하겠습니다.
아래 순서이며 전부 열혈강의 책에 있습니다.
1. 스마트 포인터 (두 예제 중에 첫 번째 꺼)
2. 펑터 (첫 번째 예제)
3. 스트링연산자 (역시 첫 번째 예제)
1. 스마트 포인터
: 클래스 객체를 포인터 문법처럼 쓸 수 있는 것입니다.
어떻게? 포인터 문법에 사용되는 각종의 연산자를 오버로딩 해서요.
왜 쓰냐? 아래처럼 소멸자를 이용하여, 프로그램 종료 시에 동적할당 된 주소를 소멸시켜 주려구요.
~SmartPtr()
{
delete posptr;
}
스마트한 발상이네요.
나머지는 아래 코드의 주석을 참조하세요.
=====================
#include <iostream>
using namespace std;
class Point
{
private:
int xpos, ypos;
public:
Point(int x=0, int y=0) : xpos(x), ypos(y)
{ cout<<"Point 객체 생성"<<endl; }
~Point()
{
cout<<"Point 객체 소멸"<<endl;
}
void SetPos(int x, int y)
{ xpos=x; ypos=y; }
friend ostream& operator<<(ostream& os, const Point& pos);
};
ostream& operator<<(ostream& os, const Point& pos)
{
os<<'['<<pos.xpos<<", "<<pos.ypos<<']'<<endl;
return os;
}
class SmartPtr{
private:
Point * posptr;
public: SmartPtr(Point * ptr) :
posptr(ptr) //처음 객체 생성 시에, 객체(Point형 포인터ptr)하게
{ } //되면, 그 객체의 posptr 값은 ptr 값이 됩니다.
//왜 이러느냐? 나중에 이 객체 sptr 자신이 ptr을 대체하려고 ptr 값을
//자신의 몸 안 (posptr)에 복사해 놓는 것입니다. 저그 같습니다.
Point& operator*() const //코드에서 ‘*(객체)’하면 호출되고, 그 객체 몸 안에 있는
{ //*posptr 값을 Point형으로 토해 냅니다. 그럼 ‘*(객체)’는
return *posptr; //*posptr 즉, ‘Point형 객체’로 대변신!!
}
Point* operator->() const //역시 위와 같은 연산자 오버로딩. 반환형을 유심히 보세요.
{
return posptr;
}
~SmartPtr()
{
delete posptr; //이 부분이 없으면 동적할당 해제가 안됩니다. 안 스마트 하지요.
}
};
int main(void)
{
SmartPtr sptr1(new Point(1, 2));
SmartPtr sptr2(new Point(2, 3));
SmartPtr sptr3(new Point(4, 5));
cout<<*sptr1; //위 연산자 오버로딩에 의해 *sptr1이 *ptr1로 되고,
cout<<*sptr2; cout<<*sptr3;
sptr1->SetPos(10, 20); //연산자 오버로딩에 의해 ptr ->setpos(10, 20)이 되죠.
sptr2->SetPos(30, 40);
sptr3->SetPos(50, 60);
cout<<*sptr1;
cout<<*sptr2;
cout<<*sptr3;
return 0;
}
이상 스마트하게 설명을 마쳤습니다.
목 운동 좀 하고, 아래 펑터 예제로 들어가 봅시다.
2. 펑터
스마트 포인터가 객체를 포인터처럼 쓰게 하는 거고, 이를 위해 포인터 관련 연산자를 오버로딩 합니다. 마찬가지로,
펑터는 객체를 함수처럼 쓸 수 있게 하는 것이며, 이를 위해 함수 관련 연산자 즉, () 연산자를 오버로딩 합니다.
아래 코드 중에서,,,
====================================
#include <iostream>
using namespace std;
class Point
{
private: int xpos, ypos;public:
Point(int x=0, int y=0) : xpos(x), ypos(y) { }
Point operator+(const Point &pos) const
{
return Point(xpos+pos.xpos, ypos+pos.ypos);
}
friend ostream& operator<<(ostream& os, const Point& pos);
};
ostream& operator<<(ostream& os, const Point& pos)
{
os<<'['<<pos.xpos<<", "<<pos.ypos<<']'<<endl; return os;
}
class Adder //아래 부분에서 () 연산자를 인수의 자료형별로 3가지로 오버로딩 하네요.
{
public int operator()(const int &n1, const int &n2) //int 관련한 이 부분을 지워봅시다.
{
return n1+n2;
}
double operator()(const double &e1, const double &e2)
{
return e1+e2;
}
Point operator()(const Point &pos1, const Point &pos2)
{
return pos1+pos2;
}
};
int main(void)
{
Adder adder;
cout<<adder(1, 3)<<endl; //그러면 이 코드는 어떻게 될까요??
cout<<adder(1.5, 3.7)<<endl; //double관련 연산자 오버로딩을 지우면 얘는 어케될까요?
cout<<adder(Point(3, 4), Point(7, 9)); //Point관련 연산자 오버로딩을 지우면??
return 0; //결과와 이유를 설명하세요. 숙제입니다.
}
3. String 클래스 만들기
C언어에서 char*를 썼던 곳에, C++에서 우리는 string을 씁니다. 용법이 비슷해서 string을 char*와 같이 기본자료형 비스무리한 걸로 알고 쉽습니다. 하지만, char*는 기본자료형 포인터 이며, string은 사용자정의 자료형입니다.
따라서 String str1 하면, char*와 닮은 string형 변수 str1이 생기는 것이 아니라,
string형 클래스 객체 str1이 생기는 것이죠.
그리고 이 string형 객체 str1을 char형 포인터 변수 Pchar처럼 동작하게끔 string 클래스에 연산자 오버로딩을 시켜놓은 것이며, 우리는 이 클래스를 가져다 쓰는 것입니다.
자, 그럼 어떤 연산자를 오버로딩 해야 할까요?
=============
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string str1="I like "; //일단 문자열이 들어가야 하므로 = 연산자에 대해 대입이
string str2="string class"; //되게끔 오버로딩 시켜 놓아야 합니다.
string str3=str1+str2; //char*와는 다르게 +기능이 있으며, 이 역시 +연산자에 대한
//오버로딩으로 가능해 진 것입니다.
cout<<str1<<endl; //<<연산자에 대해 ‘operator<< (const String str)' 이렇게
cout<<str2<<endl; //오버로딩 되어 있을까요?? 그럴까요?? 숙제입니다. 맞추면
cout<<str3<<endl; //소개팅 나가 드립니다.
str1+=str2; //+= 연산자에 대해서도 오버로딩 해야 하고,
if(str1==str3) //비교 연산자 ===에 대해서도 오버로딩 해야 하고,
cout<<"동일 문자열!"<<endl; else cout<<"동일하지 않은 문자열!"<<endl;
string str4; cout<<"문자열 입력: "; cin>>str4; //cout에 쓰인 <<처럼, cin에 쓰인 >> 연산자도 오버로딩 해야 함.
cout<<"입력한 문자열: "<<str4<<endl;
return 0;
}
'C언어 업무보고' 카테고리의 다른 글
업무보고 메모 (0) | 2014.10.29 |
---|---|
링크드리스트 중간삽입 20140421 (0) | 2014.04.21 |
140417 연결리스트 : 연결리스트의 삽입 (0) | 2014.04.17 |
140416 분할컴파일 및 소스인사이트 툴 사용법 (0) | 2014.04.16 |
아트메가 불 밝히기 : volatile, 반복문 (0) | 2014.04.11 |