일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 패스트캠퍼스
- 알버트
- 한번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online.
- 한번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지
- R
- 한번에끝내는Java/Spring웹개발마스터초격차패키지
- SKT
- 직장인자기계발
- 패캠챌린지
- AI
- 한번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online
- 직장인인강
- albert
- 패스트캠퍼스후기
- Today
- Total
제주 탈출 일지
연산자 오버로딩 예제 본문
뇌를 자극하는 C++ STL의 연산자 오버로딩 예제를 공부하면서 느낀게 많아서 정리하려고 한다.
각각의 예제 소스코드를 올려놓았다.
#include <iostream>
using namespace std;
class Point
{
int x;
int y;
public :
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
void Print() const { cout << x << "," << y << endl;}
int GetX() const { return x; }
int GetY() const { return y; }
void SetX(int argx) { x = argx;}
void SetY(int argy) { y = argy;}
friend const Point operator-(const Point& argL, const Point& argR);
};
// 내 맘대로 짠 버전.
/*
const Point operator-(const Point& argL, const Point& argR)
{
Point pt;
pt.SetX(argL.GetX() - argR.GetX());
pt.SetY(argL.GetY() - argR.GetY());
return pt;
}
*/
// 전역함수를 이용한 버전.
/*
const Point operator-(const Point& argL, const Point& argR)
{
return Point( argL.GetX() - argR.GetX(), argL.GetY() - argR.GetY() );
}
*/
// friend 함수를 사용한 버전
const Point operator-(const Point& argL, const Point& argR)
{
return Point(argL.x - argR.x, argL.y- argR.y);
}
int main()
{
Point p1(2, 3), p2(5,5);
Point p3;
p3 = p1 - p2;
p3.Print();
return 0;
}
이 예제는 전역함수 오버로딩 예제이다. 전역함수 오버로딩을 사용하기 위해서는 클래스의 프라이빗 멤버에 접근해야 하는데, 그를 위해 필요한 것이 Getter,Setter 혹은 프렌드 함수이다.
이 예제는 p3에 p1 - p2를 한 값을 대입하려하는데, 오버로딩을 어떻게 정의할 것이냐를 물어보고 있다. 함수들의 공톰점은 프라이빗 멤버에 접근하여 x값끼리 빼고, y값끼리 뺴서 그 값을 지닌 객체를 리턴하고 있습니다.
제가 짠 버전이외의 다른 함수에서는 return Point( 세부 인자... ) 형태로 반환을 진행하는데, 여기서 Point()는 암시적인 객체 호출로 이름이 없는 Point형 객체이다.
그 다음은 문제 4번이다.
#include <iostream>
using namespace std;
#include <cstring>
class String
{
char buf[100];
public :
String(const char* sz) {strcpy(buf, sz);}
operator const char* ()
{
return buf;
}
};
int main()
{
String s("Hello");
const char* sz = s; //buf의 주소가 포인터 sz에 저장됨. 중요중요!!!!!!
cout << sz << endl;
return 0;
이 문제는
"String s("Hello");
const char* sz = s;" 가 성립하기 위해서 String 클래스를 정의하라. 가 문제였다.
내가 이 문제에서 엄청나게 삽질을 했는데, 나는 당연히 operator=에 대한 오버로딩을 하라고 생각했다.
근데 막상 짜려고 하니, 이 operator를 정의한 클래스의 객체가 이 연산을 호출해야 사용이 가능한데, const char* sz가 먼저 나와서 String 클래스의 s가 단순 대입을 시도하고 에러가 나는,,, 그런 인피니티에 빠졌다.
결국 못풀고 답을 봤는데, operator const char*() 를 정의하더라...
(감정변화 : ?? -> 헐.. -> 난이거못풀었겠다.)
C++ 참고서를 찾아보니, const char* sz = s;에서는 암시적으로 데이터 변환을 시도한다. sz는 char* 형이고 s는 String형이기 때문. 따라서 const char* sz = (const char*)s;를 컴파일러에서 자동으로 실행시켜주는 것과 같은 말이다.
따라서 operator const char* 형 연산을 정의해야 컴파일러에서 이 연산을 가져다가 저 문장에 적용하여 에러가 생기지 않는다.
문제 5번인데 참고해보길 바란다. 문제는 main의 있는 내용이 주어지고, 그 내용을 컴파일할 수 있도록 클래스를 작성하는 것이다.
#include <iostream>
using namespace std;
#include <cstring>
//얕은 복사.
/*
class String
{
char buf[100];
public :
String(const char* sz)
{
strcpy(buf, sz);
}
};
*/
//깊은 복사.
class String
{
char* buf;
public:
String(const char* sz)
{
buf = new char[strlen(sz) + 1];
}
String()
{
delete [] buf;
}
const String& operator=(const String& arg)
{
delete [] buf;
buf = new char[strlen(arg.buf) + 1];
strcpy(buf, arg.buf);
return *this;
}
};
int main()
{
const char* sz = "Hello!";
String s("Hi~!");
s = sz;
return 0;
}
다시금 느껴지는 띵언.
기본이 중요하다.
'C++' 카테고리의 다른 글
string 형 처리. (0) | 2020.10.10 |
---|---|
vector 컨테이너 (0) | 2020.10.10 |
양방향 연결리스트(DLinkedList) - C++ (0) | 2020.09.03 |
스마트 포인터(smart pointer) (0) | 2020.08.18 |
템플릿 (함수, 클래스) (0) | 2020.08.17 |