숏컷 코드
cpp
class Builder {
public:
Builder& set_name(std::string n) {
name_ = std::move(n);
return *this; // 메서드 체이닝
}
Builder& set_port(int p) { port_ = p; return *this; }
Server build() { return Server{name_, port_}; }
private:
std::string name_;
int port_ = 8080;
};
auto server = Builder{}.set_name("localhost").set_port(9090).build();문법
this — 암묵적으로 전달되는 자기 참조
멤버 함수를 호출할 때 컴파일러는 **호출 대상 객체의 포인터(this)**를 첫 번째 인자로 암묵적으로 전달합니다. 멤버 함수 안에서 name_이라고 쓰는 것은 실제로는 this->name_과 동일합니다.
cpp
class Counter {
int value_;
public:
void increment() {
++value_; // 실제: ++this->value_
}
Counter* self() {
return this; // 자신의 포인터
}
};
// 컴파일러가 변환하는 방식 (개념적):
// void Counter::increment(Counter* this) { ++this->value_; }const 멤버 함수에서의 this
const 멤버 함수 안에서 this는 const T* 타입이 됩니다. 멤버 변수를 수정하면 컴파일 오류가 납니다.
cpp
class Circle {
double radius_;
public:
double area() const {
// this는 const Circle* — 수정 불가
// radius_ = 5; // ❌ const 객체의 멤버 수정 불가
return 3.14159 * radius_ * radius_; // ✅ 읽기만
}
};
const Circle c{5.0};
c.area(); // ✅ const 함수
// c.resize(); // ❌ 비const 함수 호출 불가*this 반환 — 메서드 체이닝
*this를 반환하면 같은 객체에 대해 멤버 함수를 연속 호출(체이닝)할 수 있습니다. Builder 패턴과 스트림(cout)이 이 방식을 사용합니다.
cpp
class Query {
std::string sql_;
public:
Query& from(std::string table) { sql_ += "FROM " + table + " "; return *this; }
Query& where(std::string cond) { sql_ += "WHERE " + cond + " "; return *this; }
Query& limit(int n) { sql_ += "LIMIT " + std::to_string(n); return *this; }
std::string build() const { return "SELECT * " + sql_; }
};
auto q = Query{}
.from("users")
.where("age > 20")
.limit(10)
.build();체크포인트
| 상황 | 적합한 선택 |
|---|---|
| 상태를 읽기만 하는 함수 | const 멤버 함수 |
| 연속 호출 지원 | T& func() { ...; return *this; } |
| 자신의 포인터 필요 | this |
| 이름 충돌 해결 | this->member = param |
주의할 점
로컬 변수와 멤버 변수 이름이 같으면 this->로 명시해야 합니다. 그렇지 않으면 로컬 변수를 가리킵니다.
cpp
class Widget {
int width_;
public:
// ❌ 매개변수 width가 멤버 width_를 가림
void set_width(int width) {
width = width; // 매개변수를 자기 자신에 대입 — 멤버 변경 없음
}
// ✅ this->로 명확히 구분
void set_width_ok(int width) {
this->width_ = width; // 또는 멤버 변수에 _ 접미사로 구분
}
// ✅ 멤버 변수에 _ 접미사 사용 (관례)
void set(int width) { width_ = width; } // 이름이 달라 혼동 없음
};참고 링크
1 sources