2020. 9. 10. 17:38ㆍ컴퓨터 수업/C++
@연산자 오버로드
클래스 변수(객체)를 이용하여 프로그램을 작성하다 보면 클래스 변수끼리 덧셈,뺄셈,곱셈 등의 연산이 수행되도록 해야 하는 경우가 발생한다. 그러나 일반 연산자를 사용하여 객체끼리 덧셈이나 뺄셈을 수행할수는 없다.
C++에서는 기존의 연산자의 의미를 사용자가 임의로 변경하여 사용할 수 있도록 하는 연산자 오버로드(operator overload) 기능을 제공한다.
물론 +를 -로 기능하도록 바꾸고, *을 /로 바꾸는 그런 장난스러운 짓도 할 수 있겠지만, 본래 의미는 C++에서 기본적으로 제공하는 연산자의 기능을 특정 객체에 대해 동작하도록 사용자가 새로운 기능의 의미로 재정의 하는 것을 말한다. 따라서, 연산자를 오버로드해도 연산자가 가지고 있는 본래의 기능(의미)는 상실되지 않도록 해야한다.
@연산자 "오버로드"
지난 포스트에서 오버로드가 c++의 다형성을 지원하는 기능이라 하였다. +가 기본적인 자료형에 대해서 더하는 것이 아니라, 객체 끼리 더할 수 있게 된다는것이 왜 오버로드이고, 왜 다형성을 지원하는 것인가?
+에 새로운 자료형datatype 을 사용할 수 있게된다. (그것이 바로 객체composite data type) --> 오버로드
서로 다른 datatype에 대해서 특정 연산자를 이해할 수 있게된다 --> 다형성
@연산자 오버로드"하는법"
연산자를 오버로드하려면 연산자 함수를 정의하여야 한다.
-> 새로운 format을 만들어야 한다는 뜻
연산자 함수는 operator라는 예약어keyword를 갖는 함수로 이때, 연산자 함수는 클래스의 멤버 함수(멤버 연산자 함수)이거나 프렌드 함수(프렌드 연산자 함수)로 정의된다.
->operator라는 keyword가 붙는 새로운 함수를 만들건데, 이 함수는 멤버함수 이거나 외부+프렌드 함수로 클래스 내부의 데이터 멤버에 접근 할 수 있어야 된다는 뜻.
연산자 함수를 클래스의 멤버 함수나 프렌드 함수로 정의하는 방법은 일반 함수를 클래스의 멤버 함수나 프렌드 함수로 정의하는 방법과 동일하다.
이때, 그 새로운 format은 (클래스의 스코프나 프렌드를 제외하면) 다음과 같다.
datatype operator# ( argument )
{
...
}
이때 datatype은 대부분 객체의 클래스형이 될것이다. (객체끼리의 연산을 위해서 연산자 오버로딩 하는 경우가 대부분이라 했으니) 따라서 다음과 같다.
classname operator#(argument)
{
...
}
그리고 이때 #의 위치에는 오버로드할 연산자를 기술한다.
@이항 연산자의 오버로드
연산자 함수로 이항 연산자를 오버로드할 때는 연산자 함수 classname operator#(argument) 의 아규먼트는 단 하나이다.
(이항 연산자니까! -> 즉 특정 연산자에 대해서 연산할 대상(target = argument)가 단 하나이기 때문이다,
즉 class1 + class2 의 경우 <class1+>(class2) 로써 this 포인터는 class1+ 함수에 전달된다.
이때, 연산자의 우측에 놓인 객체가 멤버 연산자 함수의 가인수에 전달되며/ 연산자의 좌측에 놓인 객체(scope)가 멤버 연산자 함수를 호출하게 된다. (멤버 연산자 오버로드와 프렌드함수를 이용한 오버로드를 하나의 예시에 대해 2번 작성하겠다.)
+scope의 의미 : 해당 멤버 함수에 this 포인터를 전달한다.
@메소드를 이용한 이항 연산자의 오버로드 코드
#include <iostream>
using namespace std;
class vector
{
private:
int x, y;
public:
vector(int i = 3, int y = 2);
vector operator+(vector);
friend void get_data(vector);
};
vector::vector(int i, int j)
{
this->x = i, this->y = j;
}
vector vector::operator+(vector b) // instance class::operator+(target instance)를 알아둘것
{
b.x = this->x + b.x; // 어차피 복사생성된것이니
b.y = this->y + b.y;
return b;
}
void get_data(vector i)
{
cout << "[" << i.x << " , " << i.y << "]" << endl;
}
int main()
{
vector a, b(1, 1), c;
c = a + b;
get_data(c);
}
@프렌드함수를 이용한 이항 연산자 코드
#include <iostream>
using namespace std;
class vector
{
private:
int x, y;
public:
vector(int i = 3, int y = 2);
friend vector operator+(vector a, vector b);
friend void get_data(vector i);
};
vector::vector(int i, int j)
{
this->x = i, this->y = j;
}
vector operator+(vector a, vector b)
{
b.x = a.x + b.x; // 어차피 복사 된거니까~
b.y = a.y + b.y;
return b;
}
void get_data(vector i)
{
cout << "[" << i.x << " , " << i.y << "]" << endl;
}
int main()
{
vector a, b(1, 1), c;
c = a + b;
get_data(c);
}
@메소드와 프렌드의 차이 <>를 function이라 하면 // 중요해!
<class+>(argument(target class)>와
(argument(target class1) <+> (argument(target class2) 의 차이이다.
@실습 문제
3차원의 두 벡터 a와 b가 주어졌을 때, 두 벡터를 내적 및 더하는 프로그램을 작성하시오.
*연산자 오버로딩을 이용해서 아래에 주어진 메인 함수가 출력 예제와 동일하게 동작하도록 VecType Class를 구현하시오.
*클래스 생성자로 3개의 정수형 파라미터 입력을 받아 VecType 인스턴스가 초기화될 수 있도록 하시오.
#include <iostream>
#include "VecType.h"
using namespace std;
int main()
{
VecType a(2, 5, 8);
VecType b(3, 4, 7);
int ip;
ip = a.inner(b);
cout << ip << endl;
VecType c = a + b;
cout << c << endl;
return 0;
}
VecType.h
#pragma once
using namespace std;
class VecType
{
private:
int vector[3];
public:
VecType(int i = 1, int j = 2, int k = 3);
int inner(VecType b);
VecType operator+(VecType);
friend ostream& operator<<(ostream& os , VecType b);
};
VecType::VecType(int i, int j, int k)
{
vector[0] = i, vector[1] = j, vector[2] = k;
}
int VecType::inner(VecType b)
{
int temp = 0;
for (int i = 0; i < 3;i++)
{
temp += (this->vector[i] * b.vector[i]);
}
return temp;
}
VecType VecType::operator+(VecType b)
{
b.vector[0] = b.vector[0] + this->vector[0];
b.vector[1] = b.vector[1] + this->vector[1];
b.vector[2] = b.vector[2] + this->vector[2];
return b;
}
ostream& operator<<(ostream& os,VecType b)
{
os << "[" << b.vector[0] << " , " << b.vector[1] << " , " << b.vector[2] << "]" << endl;
return os;
}
언젠가 ostream도 이해할 날이 오겠징
VecType b말고 cosnt VecType &b를 애용하자. 복사생성자때매...
'컴퓨터 수업 > C++' 카테고리의 다른 글
파일 입출력(fstream) (0) | 2020.09.14 |
---|---|
const에 관한 얘기 (0) | 2020.09.13 |
friend 함수 (0) | 2020.09.10 |
오버로딩과 다형성 (오버로딩은 그냥 다른 datatype 지원 그 자체다.) (0) | 2020.09.10 |
this 포인터 (0) | 2020.09.10 |