Class
C++에서 class
는 객체 지향 프로그래밍(Object-Oriented Programming, OOP)의 핵심적인 구성 요소다.
클래스는 관련된 데이터(멤버 변수)와 해당 데이터를 처리하는 함수(멤버 함수 또는 메서드)를 하나로 묶은 사용자 정의 데이터 타입이다.
- 캡슐화 (Encapsulation): 데이터와 함수를 하나로 묶고, 외부로부터 데이터의 직접적인 접근을 제한하여 무결성을 보장. 이는
private
,protected
같은 접근 지정자를 통해 구현. - 상속 (Inheritance): 기존 클래스(부모 클래스)의 속성과 메서드를 새로운 클래스(자식 클래스)가 물려받아 재사용하고 확장할 수 있다.
- 다형성 (Polymorphism): 같은 이름의 메서드가 다른 클래스에서 다른 방식으로 동작할 수 있게 하는 기능. 가상 함수(virtual function)를 통해 구현.
- 기본 접근 지정자:
class
키워드로 정의된 멤버들의 기본 접근 수준은private
. 즉, 접근 지정자를 명시하지 않으면 모든 멤버는 클래스 외부에서 접근할 수 없다.
구조체(Struct)
struct
는 C 언어에서 유래된 개념으로, 여러 관련 데이터를 하나의 단위로 묶기 위한 사용자 정의 데이터 타입이다.
C++에서는 struct
의 기능이 크게 확장되어 class
와 거의 동일한 기능을 제공한다.
C++에서의 특징
- C++의
struct
는 멤버 변수뿐만 아니라 멤버 함수, 생성자, 소멸자를 가질 수 있다. class
처럼 상속을 구현할 수 있다.- 기본 접근 지정자:
struct
키워드로 정의된 멤버들의 기본 접근 수준은public
. 즉, 접근 지정자를 명시하지 않으면 모든 멤버는 구조체 외부에서 자유롭게 접근할 수 있다.
Class와 Struct의 차이
C++에서 class
와 struct
의 유일한 차이점은 기본 접근 지정자와 기본 상속 접근 지정자다.
구분 | class |
struct |
---|---|---|
멤버 기본 접근 지정자 | private |
public |
상속 기본 접근 지정자 | private |
public |
사용 의도에 따른 차이 (Semantic Difference)
기술적으로는 거의 동일하지만, 다음과 같은 관례적인 용도 차이가 있다.
struct
를 사용하는 경우:- 여러 데이터 필드를 하나로 묶는 것이 주된 목적일 때 (Plain Old Data, POD).
- 모든 데이터가 외부에 공개되어도 괜찮을 때.
- 복잡한 멤버 함수나 로직이 필요 없을 때.
- 예: 좌표(x, y), 학생 정보(이름, 학번, 학점) 등.
class
를 사용하는 경우:- 데이터와 이를 처리하는 메서드를 함께 캡슐화해야 할 때.
- 클래스 내부의 상태(데이터)를 보호하고, 정해진 인터페이스(public 메서드)를 통해서만 상태 변경을 허용해야 할 때 (불변성 유지).
- 상속, 다형성 등 객체 지향의 기능을 적극적으로 활용할 때.
실습 코드
기본 접근 지정자 차이
#include <iostream>
#include <string>
// Class 예제
class PersonClass {
// 기본 접근 지정자가 private이므로, 이 멤버는 외부에서 직접 접근 불가
std::string name;
int age;
public:
// 외부와 소통하기 위한 public 인터페이스
PersonClass(std::string n, int a) : name(n), age(a) {}
void introduce() {
std::cout << "Class - 이름: " << name << ", 나이: " << age << std::endl;
}
};
// Struct 예제
struct PersonStruct {
// 기본 접근 지정자가 public이므로, 이 멤버들은 외부에서 직접 접근 가능
std::string name;
int age;
// 구조체도 생성자와 멤버 함수를 가질 수 있음
PersonStruct(std::string n, int a) : name(n), age(a) {}
void introduce() {
std::cout << "Struct - 이름: " << name << ", 나이: " << age << std::endl;
}
};
int main() {
// PersonClass 객체 생성
PersonClass person_c("홍길동", 30);
person_c.introduce(); // public 멤버 함수이므로 호출 가능
// person_c.name = "임꺽정"; // 컴파일 에러! 'name'은 private 멤버이므로 접근 불가
// PersonStruct 객체 생성
PersonStruct person_s("성춘향", 20);
person_s.introduce(); // public 멤버 함수 호출
// struct의 멤버는 기본적으로 public이므로 외부에서 직접 수정 가능
person_s.name = "이몽룡";
person_s.age = 22;
person_s.introduce();
return 0;
}
상속에서의 기본 접근 지정자 차이
#include <iostream>
// 부모 클래스/구조체
class Base {
public:
void public_func() { std::cout << "Base public function" << std::endl; }
protected:
void protected_func() { std::cout << "Base protected function" << std::endl; }
private:
void private_func() { std::cout << "Base private function" << std::endl; }
};
// class로 상속: 기본적으로 private 상속
// class DerivedClass : Base와 동일
class DerivedClass : private Base {
public:
void check_access() {
public_func(); // Base::public_func()는 private 멤버가 됨
protected_func(); // Base::protected_func()는 private 멤버가 됨
// private_func(); // 컴파일 에러! 부모의 private 멤버는 접근 불가
}
};
// struct로 상속: 기본적으로 public 상속
// struct DerivedStruct : Base와 동일
struct DerivedStruct : public Base {
public:
void check_access() {
public_func(); // Base::public_func()는 public 멤버로 유지
protected_func(); // Base::protected_func()는 protected 멤버로 유지
// private_func(); // 컴파일 에러! 부모의 private 멤버는 접근 불가
}
};
int main() {
DerivedClass derived_c;
derived_c.check_access();
// derived_c.public_func(); // 컴파일 에러! private 상속을 했기 때문에 public_func는 DerivedClass의 private 멤버가 됨
DerivedStruct derived_s;
derived_s.check_access();
derived_s.public_func(); // 호출 가능! public 상속을 했기 때문에 public 멤버로 유지됨
return 0;
}
'C++' 카테고리의 다른 글
malloc/free 와 new/delete (1) | 2025.08.26 |
---|---|
가상 소멸자 Virtual Destructor (0) | 2025.08.25 |
[단계별로 IOCP 실습] 6단계 효율적인 Send 구현 (1-Send 구현하기) (3) | 2025.08.07 |
[단계별로 IOCP 실습] 5단계 효율적인 Send 구현 (1-Send 구현하기) (3) | 2025.08.06 |
[단계별로 IOCP 실습] 4단계 네트워크와 로직 처리 스레드 분리 (4) | 2025.08.05 |