C Programming Language/C++

C++ 클래슀(Class)와 friend ν•¨μˆ˜/클래슀, this 포인터

567Rabbit 2024. 8. 27. 21:30
 

OOP(객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°)의 4가지 νŠΉμ„±(좔상화, μΊ‘μŠν™”, 상속, λ‹€ν˜•μ„±)

C++λŠ” 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ° 언어이닀  OOP(객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°) 4가지 νŠΉμ„± 1. 좔상화 : μ–΄λ–€ νŠΉμ • 정보λ₯Ό ν‘œμ‹œν•΄μ•Ό ν•˜κ³  μ–΄λ–€ 정보λ₯Ό μˆ¨κ²¨μ•Όν•˜λŠ”μ§€ μ‹λ³„ν•˜λŠ” 데 도움이 λ˜λŠ” 기술  "핡심이 뭐

codebunny99.tistory.com

 

OOP의 속성 쀑, μΊ‘μŠν™”λŠ”

μˆ¨κ²¨μ•Ό ν•  λ‚΄μš©μ„ 숨기고 ν‘œμ‹œν•  λ‚΄μš©μ„ ν‘œμ‹œν•˜λŠ” λ°©μ‹μœΌλ‘œ 정보λ₯Ό νŒ¨ν‚€μ§•ν•˜λŠ” 기술인데,

ν΄λž˜μŠ€λŠ” μΊ‘μŠν™”(+정보은닉 : information hiding)의 λŒ€ν‘œμ μΈ μ˜ˆμ΄λ‹€.

 

클래슀 λ‚΄λΆ€μ—λŠ” 데이터와 λ©”μ„œλ“œκ°€ ν¬ν•¨λ˜μ–΄ 있으며,

이λ₯Ό μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  수 μžˆλŠ”μ§€ μ—¬λΆ€λŠ” μ ‘κ·Ό μ œν•œμž(private, public, protected)에 따라 κ²°μ •λœλ‹€.

μ ‘κ·Όμ œν•œμžκ°€ μ—†μœΌλ©΄ default둜, private μ ‘κ·Ό μ œν•œμžκ°€ μ μš©λœλ‹€

 

 

 

 

 

클래슀 λ‚΄λΆ€μ—μ„œ μ •μ˜λœ λ©€λ²„ν•¨μˆ˜ : inline ν•¨μˆ˜

 

클래슀 λ‚΄λΆ€μ—μ„œ μ •μ˜λœ 멀버 ν•¨μˆ˜λŠ” 기본적으둜 inline ν•¨μˆ˜κ°€ λœλ‹€.

inline ν•¨μˆ˜λž€ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ λ°œμƒν•˜λŠ” μ˜€λ²„ν—€λ“œλ₯Ό 쀄이기 μœ„ν•΄ μ‚¬μš©λœλ‹€. 일반적으둜 ν•¨μˆ˜κ°€ 호좜되면 ν•¨μˆ˜μ˜ 싀행을 μœ„ν•΄ 호좜된 ν•¨μˆ˜μ˜ μ£Όμ†Œλ‘œ μ ν”„ν•˜λŠ” 과정이 ν•„μš”ν•œλ°, inline ν•¨μˆ˜λŠ” μ»΄νŒŒμΌλŸ¬μ—κ²Œ ν•¨μˆ˜ ν˜ΈμΆœμ„ 쀄이고, ν•¨μˆ˜μ˜ μ½”λ“œλ₯Ό 호좜 지점에 직접 μ‚½μž…ν•˜λΌκ³  μš”μ²­ν•˜λŠ” 것이닀.

 

C++μ—μ„œλŠ” 클래슀 λ‚΄λΆ€μ—μ„œ μ •μ˜λœ λͺ¨λ“  멀버 ν•¨μˆ˜λŠ” μžλ™μœΌλ‘œ inline ν•¨μˆ˜λ‘œ κ°„μ£Όλœλ‹€. 예λ₯Ό λ“€μ–΄:

class MyClass {
public:
    void myFunction() {
        // ν•¨μˆ˜ λ‚΄μš©
    }
};

 

μœ„ μ½”λ“œμ—μ„œ myFunction ν•¨μˆ˜λŠ” 클래슀 μ •μ˜ λ‚΄μ—μ„œ 직접 κ΅¬ν˜„λ˜μ–΄ μžˆμœΌλ―€λ‘œ μžλ™μœΌλ‘œ inline ν•¨μˆ˜κ°€ λœλ‹€.

 

클래슀 μ •μ˜ λ‚΄λΆ€μ—μ„œ ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λŠ” 것은 보톡 짧고 κ°„λ‹¨ν•œ ν•¨μˆ˜λ“€μ— ν•΄λ‹Ήν•œλ‹€. μ΄λŸ¬ν•œ ν•¨μˆ˜λ“€μ€ λ‹€μŒκ³Ό 같은 이유둜 inline으둜 μ²˜λ¦¬λœλ‹€.

  • νš¨μœ¨μ„±: 짧은 ν•¨μˆ˜μ— λŒ€ν•΄μ„œλŠ” ν•¨μˆ˜ 호좜의 μ˜€λ²„ν—€λ“œκ°€ μ½”λ“œ μžμ²΄λ³΄λ‹€ 더 큰 λΉ„μš©μ΄ 될 수 μžˆλ‹€. 이런 경우 inline ν•¨μˆ˜λ‘œ μ²˜λ¦¬ν•˜λ©΄ μ„±λŠ₯을 κ°œμ„ ν•  수 μžˆλ‹€.
  • νŽΈλ¦¬ν•¨: κ°œλ°œμžλŠ” 클래슀 μ •μ˜ μ•ˆμ—μ„œ ν•¨μˆ˜λ₯Ό 짧게 μ •μ˜ν•˜κ³  μ‹Άμ–΄ν•˜λŠ” κ²½μš°κ°€ λ§Žλ‹€. μ΄λ•Œ inline이 μžλ™μœΌλ‘œ 적용되면 λ³„λ„μ˜ inline ν‚€μ›Œλ“œλ₯Ό 뢙이지 μ•Šμ•„λ„ λ˜λ―€λ‘œ νŽΈλ¦¬ν•˜λ‹€.

 

C++μ—μ„œλŠ” 클래슀 λ‚΄λΆ€μ—μ„œ μ •μ˜λœ 멀버 ν•¨μˆ˜κ°€ 기본적으둜 inline ν•¨μˆ˜κ°€ 되며, μ΄λŠ” ν•¨μˆ˜ 호좜의 μ˜€λ²„ν—€λ“œλ₯Ό 쀄이고 μ½”λ“œλ₯Ό κ°„κ²°ν•˜κ²Œ μž‘μ„±ν•  수 μžˆλ„λ‘ λ•λŠ”λ‹€. κ·ΈλŸ¬λ‚˜ μ΅œμ’…μ μœΌλ‘œ inline μ—¬λΆ€λŠ” 컴파일러의 νŒλ‹¨μ— 따라 κ²°μ •λ˜λ©°, 무쑰건 inline으둜 μ²˜λ¦¬λ˜μ§€λŠ” μ•ŠλŠ”λ‹€. 이 κΈ°λŠ₯은 μ½”λ“œ νš¨μœ¨μ„±μ„ λ†’μ΄λŠ” 데 μ€‘μš”ν•œ 역할을 ν•œλ‹€.

 

 

 

 

 

λ„€μŠ€ν‹°λ“œ 클래슀(Nested Classes)

 

λ„€μŠ€ν‹°λ“œ 클래슀(Nested Class)λž€ 클래슀 내뢀에 또 λ‹€λ₯Έ 클래슀λ₯Ό μ •μ˜ν•˜λŠ” 것을 λ§ν•œλ‹€. λ„€μŠ€ν‹°λ“œ ν΄λž˜μŠ€λŠ” μ™ΈλΆ€ 클래슀의 λ©€λ²„λ‘œ μ·¨κΈ‰(μ •μ˜)되며, μ™ΈλΆ€ ν΄λž˜μŠ€μ™€ λ°€μ ‘ν•œ 관계λ₯Ό κ°€μ§€λŠ” 클래슀λ₯Ό μ •μ˜ν•  λ•Œ μœ μš©ν•˜λ‹€

 

이 ν΄λž˜μŠ€λŠ”μ™ΈλΆ€ 클래슀의 λͺ¨λ“  멀버(λΉ„κ³΅κ°œ(private), 보호(protected), 곡개(public))에 μ ‘κ·Όν•  수 μžˆμ§€λ§Œ, μ™ΈλΆ€ ν΄λž˜μŠ€λŠ” 기본적으둜 λ„€μŠ€ν‹°λ“œ 클래슀의 멀버에 μ ‘κ·Όν•  수 μ—†λ‹€λŠ” 것이 νŠΉμ§•μ΄λ‹€.

λ˜ν•œ λ„€μŠ€ν‹°λ“œ ν΄λž˜μŠ€λŠ” 두 클래슀 κ°„μ˜ κ°•ν•œ 관계λ₯Ό ν‘œν˜„ν•  수 μžˆλ‹€. μ™ΈλΆ€ 클래슀의 κ΅¬ν˜„μ„ λ•λŠ” 보쑰 클래슀λ₯Ό μ •μ˜ν•˜λŠ” 데 μœ μš©ν•˜λ‹€. μ™ΈλΆ€ 클래슀의 객체 없이도 λ…λ¦½μ μœΌλ‘œ μ‚¬μš©λ  수 μžˆλ‹€λŠ” νŠΉμ§•λ„ μžˆλ‹€. λ„€μŠ€ν‹°λ“œ 클래슀의 객체λ₯Ό 생성할 λ•Œ, μ™ΈλΆ€ 클래슀의 객체λ₯Ό λ°˜λ“œμ‹œ 생성할 ν•„μš”λŠ” μ—†λ‹€.

 

 

 

논리적인 κ·Έλ£Ήν™”: μ™ΈλΆ€ ν΄λž˜μŠ€μ™€ λ°€μ ‘ν•œ 관련이 μžˆλŠ” ν΄λž˜μŠ€λ“€μ„ λ…Όλ¦¬μ μœΌλ‘œ κ·Έλ£Ήν™”ν•  수 μžˆλ‹€. 예λ₯Ό λ“€μ–΄, νŠΉμ • ν΄λž˜μŠ€μ—λ§Œ κ΄€λ ¨λœ 헬퍼 ν΄λž˜μŠ€λ‚˜ μž‘μ€ μœ ν‹Έλ¦¬ν‹° ν΄λž˜μŠ€λ“€μ„ λ„€μŠ€ν‹°λ“œ 클래슀둜 λ§Œλ“€ 수 μžˆλ‹€.

 

μΊ‘μŠν™” κ°•ν™”: λ„€μŠ€ν‹°λ“œ ν΄λž˜μŠ€λŠ” μ™ΈλΆ€ 클래슀의 κ΅¬ν˜„ μ„ΈλΆ€ 사항을 감좔고, 클래슀 μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  수 μ—†κ²Œ ν•  수 μžˆλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ 클래슀λ₯Ό 더 μ•ˆμ „ν•˜κ³  κ΄€λ¦¬ν•˜κΈ° μ‰½κ²Œ λ§Œλ“€ 수 μžˆλ‹€.

 

이름 좩돌 방지: λ„€μŠ€ν‹°λ“œ 클래슀λ₯Ό μ‚¬μš©ν•˜λ©΄ 클래슀 이름이 μ™ΈλΆ€ 클래슀 내에 κ΅­ν•œλ˜λ―€λ‘œ, μ „μ—­ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ—μ„œμ˜ 이름 μΆ©λŒμ„ ν”Όν•  수 μžˆλ‹€.

 

class Rectangle {
public :
    class Point {       // Nested Classes 클래슀 λ‚΄ 클래슀
    public :
    	int x, y;
        void print() const { cout << x << '\t' << y ; }
        bool isEqual(const Point& p) const {return x == p.x && y == p.y ; }
    };
    
    Point leftTop, rightBottom ;
    void setLeftTop(int x, int y) { leftTop.x = x ; leftTop.y = y ; }
    void setRightBottom(int x, int y) { rightBottom.x = x ; rightBottom.y = y ; }
    bool isEqual(const Rectangle& r) const {
    	return leftTop.isEqual(r.leftTop) && rightBottom.isEqual(r.rightBottom) ;
    }
    const Rectangle& print() const {
    	leftTop.print() ; cout << '\t' ; rightBottom.print();
        return *this ;
    }
    ...
}

 

 

 

 

 

friend ν•¨μˆ˜/클래슀

 

friend ν•¨μˆ˜

 

C++μ—μ„œ friend ν‚€μ›Œλ“œλŠ” νŠΉμ • ν•¨μˆ˜λ‚˜ ν΄λž˜μŠ€κ°€ λ‹€λ₯Έ 클래슀의 λΉ„κ³΅κ°œ(private) λ˜λŠ” 보호된(protected) 멀버에 μ ‘κ·Όν•  수 μžˆλ„λ‘ ν—ˆμš©ν•˜λŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€. 이 κΈ°λŠ₯은 클래슀 μ„€κ³„μ—μ„œ νŠΉμˆ˜ν•œ 관계λ₯Ό ν‘œν˜„ν•˜κ±°λ‚˜, 클래슀 μ™ΈλΆ€μ˜ ν•¨μˆ˜κ°€ 클래슀 내뢀에 깊이 μ—°κ΄€λœ μž‘μ—…μ„ μˆ˜ν–‰ν•  ν•„μš”κ°€ μžˆμ„ λ•Œ μ‚¬μš©λœλ‹€.

 

friend ν•¨μˆ˜λŠ” νŠΉμ • 클래슀의 λΉ„κ³΅κ°œ 멀버에 μ ‘κ·Όν•  수 μžˆλ„λ‘ ν—ˆμš©λœ ν•¨μˆ˜μ΄λ‹€. friend둜 μ„ μ–Έλœ ν•¨μˆ˜λŠ” κ·Έ 클래슀의 멀버 ν•¨μˆ˜λŠ” μ•„λ‹ˆμ§€λ§Œ, ν•΄λ‹Ή 클래슀의 λͺ¨λ“  멀버(곡개, 보호, λΉ„κ³΅κ°œ)에 μ ‘κ·Όν•  수 μžˆλ‹€.

 

#include <iostream>

class Box {
private:
    double width;

public:
    // μƒμ„±μž
    Box(double w) : width(w) {}

    // friend ν•¨μˆ˜ μ„ μ–Έ
    friend void printWidth(Box& b);
};

// friend ν•¨μˆ˜ μ •μ˜
void printWidth(Box& b) {
    // Box 클래슀의 private 멀버에 μ ‘κ·Ό κ°€λŠ₯
    std::cout << "Width of box: " << b.width << std::endl;
}

int main() {
    Box box(10.0);
    printWidth(box);  // Box 클래슀의 private 멀버에 μ ‘κ·Όν•  수 있음

    return 0;
}

 

μœ„ μ½”λ“œμ—μ„œ printWidth ν•¨μˆ˜λŠ” Box 클래슀의 width 멀버에 μ ‘κ·Όν•  수 μžˆλ‹€. 이 ν•¨μˆ˜λŠ” Box 클래슀 외뢀에 μ •μ˜λ˜μ–΄ μžˆμ§€λ§Œ, friend ν‚€μ›Œλ“œλ‘œ 인해 Box 클래슀의 private 멀버에 μ ‘κ·Όν•  수 μžˆλ‹€.

 

 

 

friend 클래슀

 

friend ν΄λž˜μŠ€λŠ” λ‹€λ₯Έ 클래슀의 λͺ¨λ“  멀버(곡개, 보호, λΉ„κ³΅κ°œ)에 μ ‘κ·Όν•  수 μžˆλŠ” ν΄λž˜μŠ€μ΄λ‹€. 즉, 클래슀 Aκ°€ 클래슀 Bλ₯Ό friend둜 μ„ μ–Έν•˜λ©΄, 클래슀 BλŠ” 클래슀 A의 λͺ¨λ“  멀버에 μ ‘κ·Όν•  수 μžˆλ‹€.

 

#include <iostream>

class Engine {
private:
    int horsepower;

public:
    Engine(int hp) : horsepower(hp) {}

    friend class Car;  // Car ν΄λž˜μŠ€λŠ” Engine 클래슀의 λͺ¨λ“  멀버에 μ ‘κ·Ό κ°€λŠ₯
};

class Car {
public:
    void displayEnginePower(Engine& eng) {
        std::cout << "Engine horsepower: " << eng.horsepower << std::endl;
    }
};

int main() {
    Engine engine(300);
    Car car;
    car.displayEnginePower(engine);  // Car ν΄λž˜μŠ€κ°€ Engine 클래슀의 private 멀버에 μ ‘κ·Ό

    return 0;
}

 

이 μ˜ˆμ œμ—μ„œ Car ν΄λž˜μŠ€λŠ” Engine 클래슀의 friend둜 μ„ μ–Έλ˜μ—ˆκΈ° λ•Œλ¬Έμ— Engine 클래슀의 private 멀버인 horsepower에 μ ‘κ·Όν•  수 μžˆλ‹€.

 

 

 

 

 

this 포인터

 

this ν¬μΈν„°λŠ” C++μ—μ„œ 객체 μžμ‹ μ„ κ°€λ¦¬ν‚€λŠ” ν¬μΈν„°λ‘œ, 클래슀의 멀버 ν•¨μˆ˜ λ‚΄μ—μ„œ μ‚¬μš©λœλ‹€. this ν¬μΈν„°λŠ” 객체의 멀버 ν•¨μˆ˜κ°€ 호좜될 λ•Œ, κ·Έ ν•¨μˆ˜κ°€ 호좜된 객체의 μ£Όμ†Œλ₯Ό μžλ™μœΌλ‘œ 전달받아 μ‚¬μš©λœλ‹€. μ΄λŠ” 특히 멀버 ν•¨μˆ˜μ—μ„œ 클래슀의 멀버 λ³€μˆ˜λ₯Ό λͺ…ν™•νžˆ κ°€λ¦¬ν‚€κ±°λ‚˜, λ©”μ„œλ“œ 체이닝을 κ΅¬ν˜„ν•˜κ±°λ‚˜, 자기 μžμ‹ μ„ λ°˜ν™˜ν•˜λŠ” κ²½μš°μ— μœ μš©ν•˜λ‹€

  • 멀버 ν•¨μˆ˜ λ‚΄μ—μ„œλ§Œ μ‚¬μš©: this ν¬μΈν„°λŠ” 클래슀의 멀버 ν•¨μˆ˜ λ‚΄μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆλ‹€. 객체가 멀버 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄, thisλŠ” κ·Έ 객체의 μ£Όμ†Œλ₯Ό 가리킨닀.
  • 클래슀 νƒ€μž… 포인터: this ν¬μΈν„°λŠ” ν•΄λ‹Ή 클래슀 νƒ€μž…μ˜ 포인터이닀. 예λ₯Ό λ“€μ–΄, MyClassλΌλŠ” ν΄λž˜μŠ€κ°€ μžˆλ‹€λ©΄, thisλŠ” MyClass* νƒ€μž…μ΄λ‹€.

 

 

(1) 멀버 λ³€μˆ˜μ™€ λ§€κ°œλ³€μˆ˜ ꡬ뢄

 

클래슀의 멀버 λ³€μˆ˜μ™€ 멀버 ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ 이름이 동일할 λ•Œ, this 포인터λ₯Ό μ‚¬μš©ν•˜μ—¬ 멀버 λ³€μˆ˜λ₯Ό λͺ…ν™•νžˆ ꡬ뢄할 수 μžˆλ‹€

class MyClass {
private:
    int value;

public:
    MyClass(int value) {
        this->value = value;  // this->valueλŠ” 멀버 λ³€μˆ˜, valueλŠ” λ§€κ°œλ³€μˆ˜
    }

    void setValue(int value) {
        this->value = value;  // 멀버 λ³€μˆ˜μ— λ§€κ°œλ³€μˆ˜ 값을 ν• λ‹Ή
    }

    void printValue() {
        std::cout << "Value: " << this->value << std::endl;
    }
};

 

 

(2) λ©”μ„œλ“œ 체이닝

 

λ©”μ„œλ“œ 체이닝은 ν•˜λ‚˜μ˜ 객체에 λŒ€ν•΄ μ—¬λŸ¬ λ©”μ„œλ“œλ₯Ό μ—°μ†μ μœΌλ‘œ ν˜ΈμΆœν•  수 있게 ν•΄μ£ΌλŠ” κΈ°μˆ μ΄λ‹€. 이λ₯Ό μœ„ν•΄ 멀버 ν•¨μˆ˜λŠ” this 포인터λ₯Ό λ°˜ν™˜ν•  수 μžˆλ‹€.

class MyClass {
private:
    int value;

public:
    MyClass& setValue(int value) {
        this->value = value;
        return *this;  // ν˜„μž¬ 객체λ₯Ό λ°˜ν™˜
    }

    MyClass& incrementValue() {
        ++(this->value);
        return *this;
    }

    void printValue() {
        std::cout << "Value: " << this->value << std::endl;
    }
};

int main() {
    MyClass obj;
    obj.setValue(5).incrementValue().printValue();  // λ©”μ„œλ“œ 체이닝
    return 0;
}

 

 

 

(3) 자기 μžμ‹ μ„ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜

 

μ’…μ’… 멀버 ν•¨μˆ˜κ°€ 객체 μžμ‹ μ„ λ°˜ν™˜ν•΄μ•Ό ν•˜λŠ” κ²½μš°κ°€ μžˆλ‹€. μ΄λ•Œ this 포인터λ₯Ό μ‚¬μš©ν•΄ ν˜„μž¬ 객체의 μ°Έμ‘°λ₯Ό λ°˜ν™˜ν•  수 μžˆλ‹€

class MyClass {
public:
    MyClass* getThisPointer() {
        return this;  // 자기 μžμ‹ μ„ κ°€λ¦¬ν‚€λŠ” 포인터 λ°˜ν™˜
    }
};

int main() {
    MyClass obj;
    MyClass* p = obj.getThisPointer();  // obj의 μ£Όμ†Œλ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터 p
    return 0;
}