달력

52024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

 

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을 씁니다. 용법이 비슷해서 stringchar*와 같이 기본자료형 비스무리한 걸로 알고 쉽습니다. 하지만, char*는 기본자료형 포인터 이며, string은 사용자정의 자료형입니다.

따라서 String str1 하면, char*와 닮은 string형 변수 str1이 생기는 것이 아니라,

string형 클래스 객체 str1이 생기는 것이죠.


그리고 이 string형 객체 str1char형 포인터 변수 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;

}

 

 

 

 


Posted by C언어 보이
|