Function Overloading (ν¨μ μ€λ²λ‘λ©)
void print(int x) { std::cout << "int: " << x << std::endl; }
void print(double x) { std::cout << "double: " << x << std::endl; }
void print(std::string x) { std::cout << "string: " << x << std::endl; }
int main()
{
print(10); // print(int) νΈμΆ
print(3.14); // print(double) νΈμΆ
print("hello"); // print(std::string) νΈμΆ
return 0;
}
Operator Overloading (μ°μ°μ μ€λ²λ‘λ©)
struct ComplexNum
{
double real;
double imag;
ComplexNum(double r, double i) : real{r}, imag{i} {}
void print() const
{
std::cout << real << " + " << imag << "i" << std::endl;
}
};
// + μ°μ°μ μ€λ²λ‘λ© (μ μ ν¨μλ‘ κ΅¬ν)
ComplexNum operator+(const ComplexNum& lhs, const ComplexNum& rhs)
{
return ComplexNum{lhs.real + rhs.real, lhs.imag + rhs.imag};
}
int main()
{
ComplexNum c1{1, 1};
ComplexNum c2{1, 2};
ComplexNum c3 = c1 + c2; // operator+(c1, c2) νΈμΆ
c3.print(); // 2 + 3i
return 0;
}
λ©€λ² ν¨μ vs μ μ ν¨μ
// λ©€λ² ν¨μλ‘ κ΅¬ν
struct ComplexNum
{
ComplexNum operator+(const ComplexNum& rhs) const
{
return ComplexNum{real + rhs.real, imag + rhs.imag};
}
};
// c1 + c2 β c1.operator+(c2)
// μ μ ν¨μλ‘ κ΅¬ν
ComplexNum operator+(const ComplexNum& lhs, const ComplexNum& rhs)
{
return ComplexNum{lhs.real + rhs.real, lhs.imag + rhs.imag};
}
// c1 + c2 β operator+(c1, c2)
μ μ ν¨μκ° νμν κ²½μ°:
2 * complex)private λ©€λ² μ κ·Ό λ¬Έμ :
friend ν€μλλ‘ μ κ·Όμ νμ©ν μ μμ§λ§, μΊ‘μνλ₯Ό κΉ¨λ¨λ¦¬λ―λ‘ κΆμ₯νμ§ μμpublicμΌλ‘ λ§λλ κ²μ΄ μ’μ (κ°λ¨ν ꡬ쑰체μ κ²½μ°)// β friend μ¬μ© (μΊ‘μν μλ°)
class ComplexNum {
double real;
double imag;
friend ComplexNum operator+(const ComplexNum&, const ComplexNum&);
};
// β
public λ©€λ² λλ getter μ¬μ©
struct ComplexNum {
double real; // κ°λ¨ν λ°μ΄ν° ꡬ쑰λ publicμΌλ‘
double imag;
};
// λλ
class ComplexNum {
double real;
double imag;
public:
double getReal() const { return real; }
double getImag() const { return imag; }
};
const (λ©€λ² ν¨μ)
class Cat
{
std::string mName;
int mAge;
public:
// const λ©€λ² ν¨μ: κ°μ²΄μ μνλ₯Ό λ³κ²½νμ§ μμ
void print() const
{
std::cout << mName << " " << mAge << std::endl;
// mAge = 10; // β μ»΄νμΌ μλ¬!
}
std::string getName() const { return mName; } // β
OK
void setAge(int age) { mAge = age; } // non-const ν¨μ
};
int main()
{
const Cat kitty{"kitty", 1};
kitty.print(); // β
OK (const ν¨μ)
kitty.getName(); // β
OK (const ν¨μ)
kitty.setAge(2); // β μ»΄νμΌ μλ¬! (non-const ν¨μ)
return 0;
}
mutable (κ°λ³ λ©€λ² λ³μ)
const λ©€λ² ν¨μ λ΄μμλ μμ κ°λ₯ν λ©€λ² λ³μconstμ μλ―Έκ° ν΄μλλ―λ‘ μ μ€νκ² μ¬μ©class Cat
{
std::string mName;
mutable int mCallCount; // mutable λ©€λ²
public:
Cat(std::string name) : mName{std::move(name)}, mCallCount{0} {}
std::string getName() const
{
mCallCount++; // β
const ν¨μμ§λ§ μμ κ°λ₯
return mName;
}
int getCallCount() const { return mCallCount; }
};
int main()
{
const Cat kitty{"kitty"};
kitty.getName();
kitty.getName();
std::cout << kitty.getCallCount(); // 2
return 0;
}
explicit (λͺ μμ λ³ν)
Implicit Conversion λ¬Έμ μν©
class Cat
{
int mAge;
public:
Cat(int age) : mAge{age} {} // λ¨μΌ λ§€κ°λ³μ μμ±μ
};
void func(Cat cat) { /* ... */ }
int main()
{
Cat kitty = 3; // β
Cat(3)μΌλ‘ μ묡μ λ³ν
func(5); // β
Cat(5)λ‘ μ묡μ λ³ν
// μλνμ§ μμ λ³νμ΄ λ°μν μ μμ!
return 0;
}
explicitμΌλ‘ ν΄κ²°
class Cat
{
int mAge;
public:
explicit Cat(int age) : mAge{age} {} // explicit ν€μλ
};
int main()
{
Cat kitty = 3; // β μ»΄νμΌ μλ¬!
Cat kitty{3}; // β
OK (λͺ
μμ μμ±)
Cat kitty(3); // β
OK (λͺ
μμ μμ±)
func(5); // β μ»΄νμΌ μλ¬!
func(Cat{5}); // β
OK (λͺ
μμ μμ±)
return 0;
}
explicit μ¬μ© κ°μ΄λλΌμΈ
explicitμ λΆμ΄λ κ²μ΄ μ’μclass Vector
{
public:
explicit Vector(int size) {} // β
explicit κΆμ₯
Vector(int x, int y, int z) {} // μ¬λ¬ λ§€κ°λ³μλ μ νμ
explicit Vector(std::vector<int> v) {} // β
explicit κΆμ₯
};
μ½λμλ νλ‘κ·Έλλ°
C++ Operator Overloading