- 오버로딩
더보기
- 오버로딩(Overloading)
같은 이름이지만 매개변수 목록은 다르게 함수를 재정의하는 것을 “오버로딩”이라 합니다. - 함수를 비슷하게 다시 작성하는 경우에는 총 세 가지 경우가 있습니다.
- 함수 중복 정의(컴파일 에러)
같은 반환 자료형, 같은 이름, 같은 매개변수 목록으로 함수를 다시 정의하는 경우 - 함수 오버라이딩
같은 반환 자료형, 같은 이름, 같은 매개변수 목록으로
부모 클래스의 멤버 함수를 다시 정의하는 경우. - 함수 오버로딩
같은 이름, 다른 매개변수 목록으로 함수를 다시 정의하는 경우.
반환 자료형은 오버로딩의 판단 기준이 아님.
- 함수 중복 정의(컴파일 에러)
- 함수 오버로딩 매칭
오버로딩된 함수 중에 어떤 함수를 호출해야 하는지 판단하는 과정. 함수
매칭 결과는 3가지가 있습니다.
첫 번째, 가장 적합한 함수를 하나 찾은 경우 -> 정상 작동
두 번째, 매칭 되는 함수를 여러 개 찾은 경우 -> 컴파일 에러
세 번째, 매칭 되는 함수를 찾을 수 없는 경우 -> 컴파일 에러
- 복사 생성자
더보기
- 복사 생성자(Copy Constructor)
생성자의 오버로딩 중 하나.
매개변수 자료형이 같은 클래스의 참조 자료형인 생성자를 복사 생성자라고 부릅니다.
새 객체를 생성 할 때, 기존에 만들어져 있던 객체를 통해 생성하고자 할 때 호출됩니다.
다시 말해, 같은 클래스에 속한 다른 객체를 참조하여 새로운 객체를 초기화합니다.
ThisClass(const ThisClass& InOther);
// 이런 형태의 생성자를 복사 생성자라 부릅니다.
// 자기 자신 자료형의 참조를 인자로 받으면 복사 생성자라고 부릅니다.
// MyVector.h
MyVector(const MyVector& InOther) {};
// Main.cpp
MyVector A = MyVector(1, 7);
MyVector B(A);
// "새 객체" B를 생성할 때, 기존에 만들어져 있던 객체 A를 통해 생성하고자 합니다.
// -> 복사 생성자 MyVector(const MyVector& InOther)가 호출됩니다.
MyVector C = MyVector(B);
// "새 객체" C를 생성할 때, 기존에 만들어져 있던 객체 B를 통해 생성하고자 합니다.
// -> 복사 생성자 MyVector(const MyVector& InOther)가 호출됩니다. - 암시적 복사 생성자
코드에 복사 생성자가 없는 경우, 컴파일러가 암시적으로 복사 생성자를 자동 생성합니다.
이 복사 생성자를 암시적 복사 생성자라고 합니다
// MyVector.h
class MyVector
{
// 분명 만들지 않았습니다.
private:
float X;
float Y;
}
// MyVector.obj
class MyVector
{
public:
MyVector() {} // 컴파일러가 암시적으로 만들어준 기본 생성자
MyVector(const MyVector& other) // 컴파일러가 암시적으로 만들어준 복사 생성자
: X(other.X)
, Y(other.Y)
{
}
private:
float X;
float Y;
}
- 연산자 오버로딩
더보기
- C++에서는 프로그래머가 연산자를 오버로딩할 수 있습니다.
단, 주의할 점은 아래와 같습니다.
MyVector& Ref; // 여기서 &는 단항 연산자가 아닙니다. 자료형 기호.
MyVector* Ptr; // 여기서 *도 단항 연산자가 아닙니다. - 특이한 연산자
Max(1, 3.14f); // 여기서 ()도 연산자입니다. 함수 호출 연산자.
int Score = Scores[10]; // []도 연산자입니다. 배열 첨자 연산자.
MyVector* Vector01 = new MyVector[10]; // new도 연산자입니다.
delete[] Vector01; // delete도 연산자입니다. - 연산자는 오버로딩 하는 방법에는 두 가지 경우가 있습니다.
1. 멤버 함수로 정의 할 수 있을 때.
2. 멤버 함수로 정의 할 수 없을 때. 즉, 전역 함수로 정의해야할 때. - 멤버 연산자를 작성하는 방법
ThisClass operator+(const ThisClass& InOther) const;
ThisClass operator-(const ThisClass& InOther) const;
ThisClass operator*(const ThisClass& InOther) const;
ThisClass operator/(const ThisClass& InOther) const;
- 전역함수의 오버로딩
더보기
- friend 키워드를 활용한 전역함수 오버로딩 문법
// MyVector.h
#include <iostream> // std::ostream
class MyVector
{
friend void operator<<(std::ostream& InOStream, const MyVector& InVector);
friend MyVector operator*(float InScalar, const MyVector& InVector);
...
};
// MyVector.cpp
...
void operator<<(std::ostream& InOStream, const MyVector& InVector)
{
...
}
MyVector operator*(float InScalar, const MyVector& InVector)
{
...
} - += 연산자와 const 멤버 함수
MyVector& operator+=(const MyVector& InOtherVector) const;
// 이렇게 선언해버리면 함수 내부에서 this를 수정할 수 없습니다.
- 연산자 오버로딩 관련 주의사항
더보기
- 새로운 연산자 기호를 만들 수는 없습니다.
ex. MyVector operator@(const MyVector& InOtherVector) const; - 오버로딩할 수 없는 연산자가 존재합니다.
1. .(멤버 접근 연산자)
2. :: (범위 지정 연산자)
3. ?: (삼항 연산자)
4. 기타 등등 - 연산자 오버로딩을 남용하지 맙시다.
할 수 있는게 많아진다고 무조건 좋은게 아닙니다. 그만큼의 유지보수 작업과 실수들이 추가됩니다.
2종 오토로 자동차를 타면 편하면서도 안전합니다.
1종 수동은 탈 수 있는건 많아지지만 실수도 많아집니다.
MyVector ResultVector = V1 << V2;
// 대체 무얼하는 연산자인지 알 수 없습니다.
// 코드를 까봐야지만 알 수 있습니다.
MyVector ResultVector = V1 ^ V2;
// 내적인지, 외적인지, 각 요소별로 단순하게 곱하는건지 알 수 없습니다.
// 마찬가지로 코드를 봐야 알 수 있습니다. - 그럼 연산자 오버로딩을 안쓰고 실수를 덜할 수 있는 방법이 있을까요?
차라리 함수를 만드는 것.
함수명 이쁘게 하고 시그니처도 잘 지어서 남들이 그 의도를 단번에 알 수 있게끔 합니다.
Vector Vector::CrossProduct(const Vector& other) const;
Vector Vector::ComponentWiseMultiply(const Vector& other) const;
'복습용 > C++' 카테고리의 다른 글
| [Unreal Engine 8기] C++ std::string과 File I/O (0) | 2026.03.25 |
|---|---|
| [Unreal Engine 8기] C++ Casting, inline 키워드, static 키워드, 예외처리 (0) | 2026.03.24 |
| [Unreal Engine 8기] C++ 상속과 다형성, 추상 클래스 (1) | 2026.03.23 |
| [Unreal Engine 8기] C++ 생성자와 소멸자 (0) | 2026.03.19 |
| [Unreal Engine 8기] C++ Console IO (0) | 2026.03.18 |