본문 바로가기

프로그래밍/C ++

[C++] 연산자 다중 정의

#include <iostream>
using namespace std;

class IntClass {
    int value;
public:
    IntClass(int n) : value(n) { } 
    IntClass operator ++ (int) { return IntClass(value++); } // 후위 연산자
    IntClass& operator += (const IntClass& n) { 
        value += n.value;
        return *this;
    }
    void disp() const { cout << value << endl; }
};

int main() {
    IntClass obj1(5);
    IntClass obj2(10);
    obj1 += obj2;
    obj1.disp(); // 출력: 15
    return 0;
}

 

대입 연산자

 

기본 대입 연산자: 객체의 데이터 멤버를 그대로 복사

묵시적 대입 연산자: 우측 피연산자 데이터 멤버를 좌측 피연산자에 그대로 복사

 

- 대입 연산자의 다중정의

// 대입 연산자의 좌측 피연산자 *this, 우측 피연산자는 fv

VecF& VecF::operator = (const VecF& fv) {
	if (n != fv.n) { // 벡터의 크기가 다르다면
	delete[] arr; // 기존 메모리를 반환하고
	arr = new float[n = fv.n]; // 새로 메모리를 할당함
}
	memcpy(arr, fv.arr, sizeof(float)*n); // 데이터 복사
	return *this;
}

 

- 이동 대입 연산자의 다중 정의

어떠한 객체에 임시 객체를 대입할 경우에는 임시 객체의 내용을 이동함으로써 대입을 효율적으로 처리할 수 있도록 이동 대입 연산자를 다중정의하여 사용할 수 있다.
좌측의 피연산자에 대입할 우측 피연산자가 rvalue일 때 사용 (대입 후 우측 피연산자의 내용이 더이상 필요 없음)
VecF& VecF::operator=(VecF&& fv) {
	delete[] arr; // 기존 메모리를 반환하고
	n = fv.n; // 우측 피연산자의 내용을 이동함
	arr = fv.arr; // fv.n , fv.arr 둘 다 동일 메모리 가리킴
	fv.arr = nullptr; 
	return *this;
}

 

std::move 함수

인수로 전달되는 객체의 rvalue 참조 반환
void swapVec(VecF& v1, VecF& v2){
	VecF tmp = move(v1); // v1의 rvalue 참조를 구하여 이동 생성자 동작
    v1 = move(v2); //v2의 ravlue 참조를 구하여 이동 대입
    v2 = move(tmp); //tmp의 rvalue 참조를 구하여 이동 대입
}

 

 

VecF tmp = std::move(v1);
  • v1의 rvalue 참조를 구하여 tmp의 초기화에 사용
  • 이동 생성자를 이용해여 tmp 생성
v1 = std::move(v2);
  • v2의 rvalue 참조를 구하여 v1에 대입
  • 이동 대입 연산자 실행

 

첨자 [ ] 연산자

배열의 첨자를 지정하는 이항 연산자
첨자를 지정하는 1개의 매개변수를 갖는 연산자
피연산자: 배열 첨자

 

int& operator[] (int i) { return arr[i]; } 
// 지정된 위치에서 값을 읽거나 저장하기 위한 연산자
int operator[] (int i) const { return arr[i]; }
// 지정된 위치의 값을 읽기 위한 연산자로, 상수 객체의 값을 읽기 위해 필요하다.

 

const 객체를 위한 [ ] 연산자

- 데이터를 읽기만 할 수 있도록 [ ] 연산자를 정의함

void f(const SafeIntArray x){
	for (int i=0 ; i < x.size() ; i++)
		cout << x[i] << endl;
}

int SafeIntArray::operator[](int i) const {  //[]는 X의 값을 수정할 수 있수도 있기 때문에 꼭 const 붙이기
...
}

//int& SafeIntArray::operator[](int i) {..} // 불가!!!!

 

- 즉 i번째 원소 반환 멤버 함수

include <iostream>
class SafeIntArray {
	int limit; // 원소의 개수
	int* arr; // 데이터 저장공간
public:
	······
	// i번 원소를 반환하는 멤버함수
	int& operator[](int i) { ······ }
	int operator[](int i) const {
	if (i < 0 || i >= limit) {
		std::cout << "첨자가 범위를 벗어나 프로그램을 종료합니다.";
		exit(EXIT_FAILURE);
	}
	return arr[i]; // i번 원소 반환
	}
};

 

- 지정된 원소에 값을 넣으려면 함수가 원소의 값을 반환 하는 것이 아닌 참조를 반환하면 된다.

#include <iostream>
class SafeIntArray {
	int limit; // 원소의 개수
	int* arr; // 데이터 저장공간
public:
	······
	// i번 원소를 반환하는 멤버함수
	int& operator[](int i) {
	if (i < 0 || i >= limit) {
		std::cout << "첨자가 범위를 벗어나 프로그램을 종료합니다.";
		exit(EXIT_FAILURE);
	}
	return arr[i]; // i번 원소 반환
	}
	..
};

 

문자열 클래스

 

C 스타일 문자열

  • 문자열은 char 형 배열 또는 char 형 포인터에 연결된 동적 할당 메모리에 저장된다.
  • 문자열의 끝을 알리기 위해 null 문자('\0') 사용한다.
  • 문자열 처리 함수
    • 문자열 길이 함수: size_t strlen(const char* str);
    • 문자열 복사 함수: char* strcpy(char* strDestination, const char* strSource);
    • 문자열 연결 함수: char* strcat(char* strDestination, const char* strSource);

자료형의 변환

  • 수신 측 클래스의 이름으로 연산자를 정의한다.
  • 반환 자료형을 별도로 표기하지 않는다.
MyString::operator char*() const {
...
}
Pencils::operator int() const {
...
}
//변환하고자 하는 자료형을 연산자로 선언
반응형

'프로그래밍 > C ++' 카테고리의 다른 글

[C++] 클래스  (0) 2024.12.05
[C++]생성자  (2) 2024.12.04
[C++] 객체 (object)  (0) 2024.12.04
[C++] 함수  (0) 2024.12.03
[C++] 자료형 (묵시적형변환)  (0) 2024.12.03