μ°μ°μ μ€λ²λ‘λ©(Operator Overloading)μ΄λ?
μ°μ°μ μ€λ²λ‘λ©μ λ§ κ·Έλλ‘ μ°μ°μ(operator)μ λμμ μλ‘ μ μ(μ¬μ μ)νλ κ²μ΄λ€.
μλ₯Ό λ€μ΄, + μ°μ°μλ μ«μλΌλ¦¬ λν λ μ°λ κ²μΈλ° μ΄ + μ°μ°μλ₯Ό μ°λ¦¬κ° λ§λ ν΄λμ€μμλ μ¬μ©ν μ μκ²λ λμμ μλ‘ μ μνλ κ²μ΄λ€. μλ‘μ΄ νμ (ν΄λμ€λ ꡬ쑰체)μ λ§λ€ λ, κ·Έ νμ μ λν΄ +, -, *, / κ°μ μ°μ°μ μμ°μ€λ½κ² μ¬μ©νκ³ μΆμ λκ° μλ€. ( ex λ κ°μ 볡μμλ₯Ό λν λ c1 + c2μ²λΌ κ°λ¨νκ² μ°κ³ μΆμ λ) κ·Έλ°λ°, κΈ°λ³Έμ μΌλ‘λ ν΄λμ€μ λν΄ + κ°μ μ°μ°μ΄ μ μλμ΄ μμ§ μμμ μΈ μ μλ€. λ°λΌμ μ§μ + μ°μ°μ΄ μ΄λ»κ² μλν μ§λ₯Ό μ μν΄ μ£Όλ κ²μ μ°μ°μ μ€λ²λ‘λ©μ΄λΌκ³ νλ€.
μ°μ°μ μ€λ²λ‘λ©μ μ¬μ©νλ©΄ μ°μ°μλ₯Ό μ¨μ μ‘°μν μ μκ² λλ―λ‘ μ½λλ₯Ό λ μ§κ΄μ μ΄κ³ κ°κ²°νκ² μμ±ν μ μλ€.
λ€μκ³Ό κ°μ μ°μ°μλ€μ μ€λ²λ‘λ λ μ μλ€.
::, ., *, ?:, sizeof, typeid λ μ°μ°μ μ€λ²λ‘λ λ μ μλ€.
μμ )
#include <iostream>
using namespace std;
class Complex {
double re, im;
public:
Complex(double re = 0.0, double im = 0.0) {
this->re = re;
this->im = im;
}
void operator += (const Complex& c) { // μ°μ°μ μ€λ²λ‘λ©μ μ¬μ©νμ¬ += μ°μ°μλ₯Ό μ μν λΆλΆ
re += c.re; // c κ°μ²΄μ μ€μ λΆλΆμ this κ°μ²΄μ μ€μ λΆλΆμ λν΄μ£Όλ μ½λ
im += c.im; // c κ°μ²΄μ νμ λΆλΆμ this κ°μ²΄μ νμ λΆλΆμ λν΄μ£Όλ μ½λ
}
void print() const {
cout << re << " + " << im << "i" << endl;
}
};
int main() {
Complex c1, c2(2, 3);
c1.print(); // 0 + 0i
c1 += c2; // c1.operator+=(c2) c1 κ°μ²΄μ reμ im κ°μ κ°κ° c2 κ°μ²΄μ reμ im κ°μ λν¨
c1.print(); // 2 + 3i
return 0;
}
operator +=λ C++μμ += μ°μ°μλ₯Ό μ€λ²λ‘λ©νμ¬ μ¬μ©νλ ν¨μμ μκ·Έλμ².
+= μ°μ°μλ κΈ°λ³Έμ μΌλ‘ λ΄μ₯λ μλ£ν(μ: int, double)μ λν΄ μ μλμ΄ μμ§λ§, μ¬μ©μ μ μ ν΄λμ€μΈ Complexμ λν΄ μ΄ μ°μ°μλ₯Ό μ¬μ©ν μ μλλ‘ μ€λ²λ‘λ©ν κ²μ΄λ€.
const Complex& cλ μ°Έμ‘°λ₯Ό ν΅ν΄ μ λ¬λ Complex νμ μ κ°μ²΄λ₯Ό μλ―Ένλ€.
const ν€μλλ μ΄ ν¨μ λ΄λΆμμ c κ°μ²΄μ κ°μ λ³κ²½ν μ μλλ‘ λ³΄μ₯νλ€.
μμ )
class Complex {
private:
double re, im; //reλ μ€μ, imλ νμ λΆλΆμ΄λ€
public:
Complex(double r = 0, double i = 0) : re(r), im(i) {}
// == μ°μ°μ μ€λ²λ‘λ©
bool operator==(const Complex& other) const {
// μ€μ λΆλΆκ³Ό νμ λΆλΆμ΄ λͺ¨λ κ°λ€λ©΄ true, κ·Έλ μ§ μμΌλ©΄ falseλ₯Ό λ°νν¨.
return (re == other.re) && (im == other.im);
}
};
bool operator==(const Complex& other) constλ == μ°μ°μκ° λ κ°μ Complex κ°μ²΄λ₯Ό λΉκ΅ν λ μ¬μ©λλ€.
λΉκ΅λ κ°μ²΄μ μ€μ λΆλΆ(re)κ³Ό νμ λΆλΆ(im)μ΄ λͺ¨λ κ°μμ§ νμΈνλ λ°©μμΌλ‘ μ΄λ£¨μ΄μ§λ€.
Non-Member Operators (λΉλ©€λ² μ°μ°μ) μ μ°μ°μ μ€λ²λ‘λ©
ν΄λμ€μ λ©€λ² ν¨μκ° μλ, ν΄λμ€ μΈλΆμμ μ μλ μ°μ°μ ν¨μμμλ μ°μ°μ μ€λ²λ‘λ©μ ν μ μλ€. μΌλ°μ μΌλ‘ μ°μ°μ μ€λ²λ‘λ©μ ν΄λμ€ λ΄λΆμμ λ©€λ² ν¨μλ‘ μ μλμ§λ§, νΉμ κ²½μ°μλ ν΄λμ€ μΈλΆμμ μ΄ μ°μ°μλ₯Ό μ€λ²λ‘λ©ν΄μΌ ν νμκ° μκΈΈ μ μλ€. μ΄λ° κ²½μ°μ friend ν¨μλ λΉλ©€λ² ν¨μ(non-member function)λ₯Ό μ¬μ©νμ¬ μ°μ°μ μ€λ²λ‘λ©μ μ μν μ μλ€.
#include <iostream>
using namespace std;
class Complex {
private:
double re, im;
public:
Complex(double r = 0, double i = 0) : re(r), im(i) {}
// friend ν¨μλ₯Ό μ¬μ©νμ¬ λ κ°μ Complex κ°μ²΄λ₯Ό λνλ ν¨μ μ μΈ
friend Complex addComplex(const Complex& c1, const Complex& c2);
void print() const {
cout << re << " + " << im << "i" << endl;
}
};
// friend ν¨μ μ μ
Complex addComplex(const Complex& c1, const Complex& c2) {
return Complex(c1.re + c2.re, c1.im + c2.im);
}
int main() {
Complex c1(1, 2); // 1 + 2i
Complex c2(3, 4); // 3 + 4i
Complex result = addComplex(c1, c2); // friend ν¨μ νΈμΆ
cout << "λ 볡μμμ ν©: ";
result.print(); // κ²°κ³Ό μΆλ ₯
return 0;
}
μ΄ μμ μμ addComplex ν¨μλ Complex ν΄λμ€μ λ©€λ²κ° μλμ§λ§, reμ imμ μ κ·Όνμ¬ λ κ°μ²΄λ₯Ό λνλ μμ μ μνν μ μλ€.
- friend ν¨μλ ν΄λμ€μ λ©€λ² ν¨μκ° μλμ§λ§, ν΄λμ€ λ΄λΆμ λΉκ³΅κ° λ©€λ²μ μ κ·Όν μ μλ€.
- friend ν¨μλ₯Ό μ¬μ©νλ©΄, ν΄λμ€ μΈλΆμμ μ μλ ν¨μλ λ§μΉ ν΄λμ€ λ©€λ² ν¨μμ²λΌ ν΄λμ€ λ΄λΆμ λ°μ΄ν°μ μ κ·Όν μ μκ² λλ€.
νΌν©ν μ°μ° (Mixed-mode Arithmetic) μμμ μ°μ°μ μ€λ²λ‘λ©
Mixed-Mode Arithmetic(νΌν©ν μ°μ°)λ νλ‘κ·Έλλ°μμ μλ‘ λ€λ₯Έ λ°μ΄ν° νμ κ°μ μ°μ°μ μλ―Ένλ€. μλ₯Ό λ€μ΄, νλμ νΌμ°μ°μκ° intνμ΄κ³ λ€λ₯Έ νΌμ°μ°μκ° doubleνμΌ λ μ΄λ€ μ¬μ΄μμ λ°μνλ μ°μ°μ νΌν©ν μ°μ°μ΄λΌκ³ νλ€.
C++μμλ λ κ°μ λ€λ₯Έ λ°μ΄ν° νμ μ μ°μ°ν λ 묡μμ μΌλ‘, ***μλμΌλ‘ ν λ³νμ΄ μΌμ΄λλ©°***, μ΄λ¬ν μ°μ°μ μ§μν μ μλλ‘ μ°μ°μλ₯Ό μ€λ²λ‘λ©ν μ μλ€.
Mixed-Mode Arithmeticμ C++μμ λ§€μ° μ μ©ν κΈ°λ₯μ΄λ€. μ°μ°μ μ€λ²λ‘λ©μ ν΅ν΄ κΈ°λ³Έ μλ£νκ³Ό μ¬μ©μ μ μ ν΄λμ€ κ°μ μ°μ°μ κ°λ₯νκ² νμ¬ λμ± μμ°μ€λ¬μ΄ μ½λ μμ±μ λλλ€. μ΄λ‘ μΈν΄ μ½λμ κ°λ μ±κ³Ό μ μ§λ³΄μμ±μ΄ ν₯μλλ©°, μ¬μ©μκ° μ μν λ°μ΄ν° νμ μ μ½κ² λ€λ£° μ μκ² λλ€.
<C++ μ°μ°μ μ€λ²λ‘λ©μ μλ νλ³ν : 묡μμ νλ³ν μ₯μ >
- μ μ°μ±: μ¬μ©μκ° μ μν Complex νμ κ³Ό κΈ°λ³Έ μλ£νμΈ doubleμ μμ°μ€λ½κ² μ°μ°ν μ μμ΄ μ½λλ₯Ό λ μ μ°νκ³ μ§κ΄μ μΌλ‘ λ§λ€ μ μμ΅λλ€.
- μ¬μ© νΈμμ±: Mixed-Mode Arithmeticμ μ¬μ©νλ©΄ 볡μμ μ°μ°μ΄ λμ± μμ°μ€λ¬μμ§λλ€. μλ₯Ό λ€μ΄, c1 + 10 λλ 10 + c1 κ°μ μ°μ°μ΄ κ°λ₯ν΄μ§λλ€.
- ν λ³νμ μ μ΄: μλ ν λ³νμ΄ μ΄λ£¨μ΄μ§λ μν©μμ μ€λ²λ‘λ©λ μ°μ°μλ μ΄λ€ μ°μ°μ΄ μ΄λ£¨μ΄μ§μ§ λͺ ννκ² μ μνλ―λ‘ μκΈ°μΉ μμ κ²°κ³Όλ₯Ό λ°©μ§ν μ μμ΅λλ€.
#include <iostream>
using namespace std;
class Complex {
private:
double re, im;
public:
Complex(double r = 0, double i = 0) : re(r), im(i) {}
// + μ°μ°μ μ€λ²λ‘λ©
Complex operator+(const Complex& c) const { // (1)
return Complex(re + c.re, im + c.im);
}
Complex operator+(const double r) const { // (2)
return Complex(re + r, im);
}
friend Complex operator+(const double r, const Complex& c); // (3)
// - μ°μ°μ μ€λ²λ‘λ©
Complex operator-(const Complex& c) const { // (4)
return Complex(re - c.re, im - c.im);
}
Complex operator-(const double r) const { // (5)
return Complex(re - r, im);
}
friend Complex operator-(const double r, const Complex& c); // (6)
void print() const {
cout << re << " + " << im << "i" << endl;
}
};
// friend ν¨μλ₯Ό ν΅ν + μ°μ°μ μ€λ²λ‘λ© (3)
Complex operator+(const double r, const Complex& c) {
return Complex(r + c.re, c.im);
}
// friend ν¨μλ₯Ό ν΅ν - μ°μ°μ μ€λ²λ‘λ© (6)
Complex operator-(const double r, const Complex& c) {
return Complex(r - c.re, -c.im);
}
int main() {
Complex c1(1, 0), c2(0, 1);
Complex c3 = c1 + c2; // (1) Complex + Complex
Complex c4 = c1 + 10; // (2) Complex + double
Complex c5 = 10 + c1; // (3) double + Complex
Complex c6 = c1 - c2; // (4) Complex - Complex
Complex c7 = c1 - 10; // (5) Complex - double
Complex c8 = 10 - c1; // (6) double - Complex
c3.print();
c4.print();
c5.print();
c6.print();
c7.print();
c8.print();
return 0;
}
λμ μ°μ°μ(Assignment Operator) '=' μ 볡μ¬(Copy)
Copy Assignment Operatorλ μ΄λ―Έ μμ±λ κ°μ²΄μ λ€λ₯Έ κ°μ²΄μ κ°μ λμ νλ μ°μ°μλ₯Ό μ μνλ ν¨μμ λλ€. λ§μ½ ν΄λμ€κ° λμ λ©λͺ¨λ¦¬ ν λΉ(μ: newλ₯Ό μ¬μ©νμ¬ ν¬μΈν°λ‘ λ©λͺ¨λ¦¬λ₯Ό ν λΉ)μ ν¬ν¨νλ λ©€λ²λ₯Ό κ°μ§κ³ μλ€λ©΄, κΉμ 볡μ¬(Deep Copy)λ₯Ό μ¬μ©ν΄μΌ ν©λλ€. κ·Έλ μ§ μμΌλ©΄ μμ 볡μ¬(Shallow Copy)λ‘ μΈν΄ μλ³Έ κ°μ²΄μ 볡μ¬λ κ°μ²΄κ° κ°μ λ©λͺ¨λ¦¬ μ£Όμλ₯Ό μ°Έμ‘°νκ² λμ΄, νλμ κ°μ²΄μμ λ©λͺ¨λ¦¬λ₯Ό ν΄μ ν λ λ€λ₯Έ κ°μ²΄μμλ μ κ·Όν μ μκ² λλ λ¬Έμ κ° λ°μν μ μλ€.
ex)
#include <iostream>
#include <cstring> // std::strlen, std::strcpy
class MyString {
private:
char* str; // λμ λ©λͺ¨λ¦¬ ν λΉμ μ¬μ©νλ λ¬Έμμ΄
public:
// μμ±μ
MyString(const char* s = "") {
str = new char[std::strlen(s) + 1];
std::strcpy(str, s);
}
// μλ©Έμ
~MyString() {
delete[] str;
}
// λ³΅μ¬ μμ±μ (κΉμ λ³΅μ¬ μ¬μ©)
MyString(const MyString& other) {
str = new char[std::strlen(other.str) + 1];
std::strcpy(str, other.str);
}
// Copy Assignment Operator (κΉμ λ³΅μ¬ μ¬μ©)
MyString& operator=(const MyString& other) {
if (this == &other) {
return *this; // μκΈ° μμ μ λν λμ
μ λ°©μ§
}
// κΈ°μ‘΄μ ν λΉλ λ©λͺ¨λ¦¬ ν΄μ
delete[] str;
// μλ‘μ΄ λ©λͺ¨λ¦¬ 곡κ°μ ν λΉνκ³ , λ°μ΄ν°λ₯Ό κΉμ 볡μ¬
str = new char[std::strlen(other.str) + 1];
std::strcpy(str, other.str);
return *this;
}
// λ¬Έμμ΄ μΆλ ₯
void print() const {
std::cout << str << std::endl;
}
};
int main() {
MyString str1("Hello, World!");
MyString str2;
str2 = str1; // Copy Assignment Operator νΈμΆ
str1.print(); // Hello, World!
str2.print(); // Hello, World!
str1 = "Goodbye!"; // μλ‘μ΄ λ¬Έμμ΄ λμ
(μμ κ°μ²΄ μμ± ν λμ
)
str1.print(); // Goodbye!
str2.print(); // Hello, World! (str1μ λ³κ²½μ΄ str2μ μν₯μ μ£Όμ§ μμ)
return 0;
}
μ΄λ―Έ μ‘΄μ¬νλ κ°μ²΄μ λ€λ₯Έ κ°μ²΄λ₯Ό λμ ν λ νΈμΆλλ€
μκΈ° μμ κ³Όμ λμ μ λ°©μ§ν ν, κΈ°μ‘΄μ ν λΉλ λ©λͺ¨λ¦¬λ₯Ό ν΄μ νκ³ μλ‘μ΄ λ©λͺ¨λ¦¬ 곡κ°μ ν λΉνμ¬ κΉμ 볡μ¬λ₯Ό μννλ€
Conversion Operator (νλ³ν μ°μ°μ)
Conversion Operatorλ ν΄λμ€μ κ°μ²΄λ₯Ό νΉμ νμ μΌλ‘ λ³ννλ λ°©λ²μ μ μνλ κ²μ λ§νλ€. μ΄λ₯Ό ν΅ν΄ ν΄λμ€ κ°μ²΄λ₯Ό λ€λ₯Έ κΈ°λ³Έ λ°μ΄ν° νμ μΌλ‘ λ³νν μ μλ€.
#include <iostream>
class MyClass {
private:
int value; // μ μ₯ν κ°
public:
// μμ±μ
MyClass(int v) : value(v) {}
operator double() const { // Conversion Operatorλ₯Ό μ μ
return static_cast<double>(value);
}
};
int main() {
MyClass obj(10);
// 묡μμ λ³ν μμ
double d = obj; // MyClass κ°μ²΄κ° μλμΌλ‘ doubleλ‘ λ³νλ¨
std::cout << "묡μμ λ³νλ κ°: " << d << std::endl;
// λͺ
μμ λ³ν μμ
double explicitDouble = static_cast<double>(obj);
std::cout << "λͺ
μμ λ³νλ κ°: " << explicitDouble << std::endl;
return 0;
}