Class

class Point {
public: // 접근 지정자
    double x; // 멤버 변수
    double y;

    // 기본 생성자
    Point() : x(0.0), y(0.0) { // x와 y를 0으로 초기화
        std::cout << "기본 생성자 호출 Point(" << x << ", " << y << ")" << std::endl;
    }

    // 파라미터를 받는 생성자
    Point(double xVal, double yVal) : x(xVal), y(yVal) {
				// ':' constructor initialization list
        std::cout << "인자를 받는 생성자 호출 Point(" << x << ", " << y << ")" 
				<< std::endl;
    }
};

Point p1; //instance, object
p1.x = 10; // (.) = dot member selection operator
p1.y = 20;
Point p2(3.5, 4.5);

class Counter {
   int count;  // default로 private
public:
   void clear() { count = 0; }  // methods
   void inc() { count++; }
   int get() { return count; }
};

public은 클래스 바깥에서 직접적으로 reference 가능 private은 method를 통해서만 접근 가능 constructor는 클래스 이름과 같은 이름의 method로 객체가 생성될 때 자동으로 호출됨. 정의하지 않으면 compiler에 의해 자동으로 생성됨. constructor는 return type이 없음.

class A { 
public:
int number = 10; 
};

int main() { 
 A a;
 A* p = new A;
 a.number = 20;
 p->number = 30;
 std::cout << a.number << std::endl;
 std::cout << p->number << std::endl; // p-> == (*p).
 std::cout << (*p).number << std::endl; 
 delete p;
}

클래스 인스턴스를 선언하는 방법은 두 가지가 있다. 클래스를 통해서 인스턴스를 생성하면 스택 영역에 메모리가 할당되며 함수실행이 끝난 이후 자동으로 해제된다. dot member selection operator를 통해서 멤버변수에 접근한다. 클래스 타입의 포인터를 사용하는 경우 new를 통해서 동적으로 heap에 할당되고 delete로 직접 해제해야 한다. arrow member selection operator(→) 혹은 (*p).을 통해 멤버변수에 접근할 수 있다.

this

클래스의 멤버함수 내에서 사용되며, 현재 객체를 가리키는 포인터. 객체의 멤버변수나 메서드에 접근할 수 있다. 포인터이기 때문에 멤버변수에 접근할 때 arrow를 쓴다. 일반적으로 멤버변수에서 this를 사용하지 않아도 암묵적으로 적용되지만 매개변수와 멤버변수의 이름이 같은 경우나 메서드 체이닝을 구현할 때는 this를 명시적으로 사용해야한다.

*this = {x,y} //현재 인스턴스에 대입 
return *this // 현재 인스턴스 리턴

class MyClass {
private:
    int value;

public:
    MyClass& setValue(int value) { // 반환 타입이 참조여야 복사하지 않음
        this->value = value; // 멤버 변수 설정
        return *this; // this를 사용하여 현재 객체를 반환
    }
    
    void printValue() const {
        std::cout << value << std::endl;
    }
};

int main() {
    MyClass obj;
    obj.setValue(10).printValue(); // 메서드 체이닝
    return 0;
}

Encapsulation

캡슐화는 데이터와 데이터를 조작하는 method를 하나의 단위로 묶는 것. 객체의 내부 상태를 보호하고 외부에서 접근하는것을 제한해 데이터 무결성을 우지할 수 있다. access specifier(public, protected, private)를 통해서 접근성을 제어하고 데이터를 은닉한다. 클래스 내부의 데이터에 접근하거나 수정하기 위해서 getter, setter 메서드를 제공한다.

class BankAccount {
private: // 데이터 은닉
    double balance; // 잔고

public: // 외부 접근 가능
    // 생성자
    BankAccount(double initialBalance) : balance(initialBalance) {}

    // 잔고 확인 메서드 (getter)
    double getBalance() const {
        return balance;
    }

    // 입금 메서드
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
};

int main(){
	BankAccount bank1(1000);
	const BankAccount bank2(2000); //상태변경 불가, const메소드만 호출가능
}

const 멤버 함수: 객체의 상태를 변경하지 않으며, const로 선언된 객체에서도 호출할 수 있습니다. const 객체: 해당 객체는 상태를 변경할 수 없으며, const 멤버 함수만 호출할 수 있습니다. const 인자: 함수가 인자로 const 타입을 받으면, 해당 인자는 수정할 수 없으며, const 멤버 함수만 호출할 수 있습니다.

friend

friend함수는 특정 클래스의 비공식적인 멤버 함수로, 해당 클래스의 private및 protected멤버에 접근할 수 있는 함수이다. 다른 클래스나 함수가 클래스의 내부 데이터에 접근할 수 있도록 허용할 수 있다. 클래스의 내부에서 friend함수를 선언하고 함수의 정의는 외부에서 이루어지는 형태로 사용한다.

class Box {
private:
    double width;

public:
    Box(double w) : width(w) {}

    // friend 함수 선언
    friend void printWidth(const Box& b);
};

// friend 함수 정의
void printWidth(const Box& b) {
    std::cout << "Width: " << b.width << std::endl; // 접근 가능
}

int main() {
    Box box(10.0);
    printWidth(box); // friend 함수 호출
    return 0;
}

Operator overloading

기존의 연산자를 재정의해서 사용자 정의 타입(클래스, 구조체) 객체 간의 연산을 자연스럽게 수행함.

std::cout << 에서 <<는 shift operator이지만 outstream객체에 대해 insertion operator로 재정의함

string type에서도 ==를 boolean을 비교하는 연산자에서 string을 비교하는 연산으로 overloading함.