1. 클래스와 구조체의 주요 차이점
1.1 C와 C++에서의 차이
먼저, C에서는 구조체(struct)가 데이터 타입을 정의하는 데 사용된다. C 언어의 구조체는 데이터를 묶어서 하나의 사용자 정의 데이터 타입으로 만드는 역할만 수행하며, 함수나 메서드를 포함하지 못한다. 반면에, C++과 같은 객체 지향 프로그래밍 언어에서는 클래스가 구조체와 유사하지만 더 많은 기능을 제공한다. C++의 구조체는 함수도 포함할 수 있지만, 기본적으로 다루는 접근 제어가 다르고, 객체 지향적인 요소가 약하다.
1.2 클래스(C++)와 구조체(C)의 주요 차이점
클래스(Class):
- 메서드 포함 가능: 클래스는 변수(멤버 변수)뿐만 아니라, 그 변수를 조작하는 함수(멤버 함수)도 포함할 수 있다.
- 캡슐화: 클래스는 캡슐화를 통해 외부에서 접근할 수 없는 데이터를 보호한다. 데이터에 접근하려면 공개된 메서드를 통해야 한다. 이를 정보 은닉이라고도 부른다.
- 접근 제어자: 클래스에서는 데이터와 메서드에 대해 접근 제어자를 명시할 수 있다. 예를 들어,
private
,protected
,public
을 사용해 각 멤버에 대한 접근을 제어할 수 있다. 기본 접근 제어자는private
이다. - 상속: 클래스는 다른 클래스의 속성과 메서드를 상속받아 코드를 재사용할 수 있다.
- 동작하는 인스턴스: 클래스의 인스턴스는 각각 독립적으로 동작하며, 상태와 동작을 가질 수 있다.
구조체(Struct) (C 언어 기준):
- 데이터 묶음: 구조체는 다양한 데이터 타입의 변수를 하나로 묶는 역할만 수행하며, 함수나 메서드를 포함할 수 없다.
- 캡슐화 없음: 구조체에는 캡슐화 기능이 없다. 구조체의 멤버는 기본적으로 모두 공개(public)된다.
- 접근 제어자 없음: 구조체는 접근 제어자가 없으며, 구조체 멤버에 대한 접근 제한을 걸 수 없다.
- 상속 불가능: 구조체는 상속 개념이 없으며, 객체 지향 프로그래밍에서 사용하는 상속과 같은 기능을 지원하지 않는다.
- 독립적 동작 없음: 구조체는 단순히 데이터를 담기 위한 그릇으로, 데이터를 가지고 있을 뿐 그 데이터를 처리하는 로직이나 동작을 포함하지 않는다.
2. C++에서 클래스와 구조체의 차이
C++에서 클래스와 구조체의 차이는 더 좁은 의미로 다가온다. 사실 C++에서는 구조체도 메서드를 가질 수 있으며, 클래스와 매우 유사하게 동작할 수 있다. 하지만 주요 차이점은 기본 접근 제어자의 차이에 있다.
- 클래스는 기본적으로 모든 멤버가
private
로 선언된다. 즉, 명시적으로 접근 제어자를 설정하지 않으면 외부에서 접근할 수 없다. - 구조체는 기본적으로 모든 멤버가
public
으로 선언된다. 즉, 명시적으로private
이나protected
로 선언하지 않으면 외부에서 접근할 수 있다.
#include <iostream>
// C++ 구조체
struct MyStruct {
int x;
void display() {
std::cout << "Struct x: " << x << std::endl;
}
};
// C++ 클래스
class MyClass {
private:
int x;
public:
void setX(int val) {
x = val;
}
void display() {
std::cout << "Class x: " << x << std::endl;
}
};
int main() {
MyStruct s;
s.x = 10; // public 멤버이므로 바로 접근 가능
s.display();
MyClass c;
// c.x = 10; // 오류! private 멤버이므로 접근 불가
c.setX(20); // public 메서드를 통해 값 설정 가능
c.display();
return 0;
}
위 코드에서 MyStruct
는 구조체지만, 멤버 함수 display()
를 가지고 있다. 하지만 x
는 public
으로 선언되어 있어 외부에서 직접 접근할 수 있다. 반면에 MyClass
는 x
가 private
으로 선언되어 있어 외부에서 직접 접근이 불가능하며, setX()
메서드를 통해서만 접근할 수 있다.
3. 캡슐화와 정보 은닉
클래스의 주요 특징 중 하나는 캡슐화이다. 캡슐화는 데이터와 그 데이터를 조작하는 메서드를 하나로 묶고, 외부에서 직접 데이터를 조작하지 못하게 보호하는 개념이다. 이를 통해 객체는 자신의 상태를 스스로 관리하고, 외부의 잘못된 접근으로부터 데이터를 보호할 수 있다.
구조체는 기본적으로 이러한 캡슐화 기능이 없기 때문에, 모든 데이터가 외부에서 직접 접근 가능하며, 잘못된 접근으로 인해 데이터가 손상될 가능성이 있다.
4. 독립적인 동작
클래스는 데이터를 처리하는 로직과 메서드를 포함하고 있어, 객체 단위로 독립적인 동작을 할 수 있다. 객체마다 고유한 상태를 가지며, 그 상태를 바탕으로 다른 동작을 수행할 수 있다.
구조체는 기본적으로 데이터의 묶음 역할만 하며, 독립적으로 동작하는 로직을 포함하지 않는다. 따라서 단순히 데이터를 저장하고, 별도의 함수에서 이 데이터를 처리하는 방식으로 사용된다.
결론
정리하면, C와 C++에서 구조체와 클래스의 차이는 크게 두 가지로 나눌 수 있다.
- C 언어에서는 구조체는 단순히 다양한 타입의 데이터를 묶는 역할을 수행하고, 메서드나 캡슐화 개념이 없다.
- C++에서는 구조체도 클래스와 거의 동일한 기능을 제공하지만, 기본 접근 제어자가
public
이라는 점에서 차이가 있다. 클래스는private
이 기본 접근 제어자이고, 상속, 캡슐화, 정보 은닉 등의 객체 지향적 기능을 더 강력하게 지원한다.
객체 지향에 프로그래밍을 해본 사람 이라면 위의 내용을 읽었을 때 하나 떠오르는게 있을 것이다. 구조체는 valueObject와 그 성격이 비슷하지 않은가 ? 라는 생각이 들것이다.
개인적인 생각이지만 c언어의 구조체 는 클래스와 비교하는것 보다는 valueObject와 비교하는게 맞다고 생각이 들어 그 둘의 차이에 대해서 정리해 보고자 한다.
1. 자바의 Value Object (VO) 특성
Value Object는 특정한 값이나 상태를 표현하기 위한 객체로, 그 값이 객체의 아이덴티티를 나타낸다. 자바에서는 VO가 주로 다음과 같은 특성을 가진다:
불변성(Immutable):
- 자바의 VO는 불변 객체로 설계되는 경우가 많다. 불변성은 한 번 객체가 생성되면 그 상태를 변경할 수 없음을 의미한다. VO 객체는 주로 읽기 전용 데이터를 포함하며, 값을 변경하기 위해서는 새로운 객체를 생성해야 한다.
public final class Point { private final int x; private final int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Point point = (Point) o; return x == point.x && y == point.y; } @Override public int hashCode() { return Objects.hash(x, y); } }
- 이와 같이 VO는 보통
final
클래스로 선언되며, 내부 필드는private
와final
로 선언된다. 이렇게 하면 객체가 생성된 후에 그 값을 변경할 수 없으므로 불변성을 보장할 수 있다.
동등성(equality):
- VO는 동등성(equality)을 값 기반으로 비교한다. 즉, 두 VO가 같은 값을 가지고 있으면 같은 객체로 간주한다. 이를 위해
equals()
와hashCode()
메서드를 재정의해야 한다. 객체의 고유한 식별자가 필요 없고, 오직 값에 따라 객체가 동일한지 아닌지를 판단한다.
- VO는 동등성(equality)을 값 기반으로 비교한다. 즉, 두 VO가 같은 값을 가지고 있으면 같은 객체로 간주한다. 이를 위해
상태를 표현하는 객체:
- VO는 상태를 저장하고 전달하는 데 주로 사용된다. 예를 들어, 좌표를 나타내는
Point
객체나 주소를 나타내는Address
객체가 전형적인 VO의 예시다. 이러한 객체는 행위(behavior)보다는 데이터(data)를 담는 데 중점을 둔다.
- VO는 상태를 저장하고 전달하는 데 주로 사용된다. 예를 들어, 좌표를 나타내는
직렬화(Serializable):
- VO는 종종 직렬화가 필요한 경우가 있다. 예를 들어, VO는 데이터베이스에 저장되거나 네트워크를 통해 전달될 때 직렬화가 가능해야 한다. 자바에서 VO는
Serializable
인터페이스를 구현하여 이러한 요구 사항을 만족할 수 있다.
- VO는 종종 직렬화가 필요한 경우가 있다. 예를 들어, VO는 데이터베이스에 저장되거나 네트워크를 통해 전달될 때 직렬화가 가능해야 한다. 자바에서 VO는
2. C/C++의 구조체(struct)와 자바 VO의 연관점
2.1 데이터 묶음 (Value Container)
- 자바의 VO와 C/C++의 구조체는 둘 다 여러 값을 하나의 단위로 묶어서 표현하는 역할을 한다. 둘 다 다양한 데이터를 하나로 묶고, 특정 상태나 값을 나타내는 데 적합하다.
- 예를 들어, 좌표를 나타내는
Point
구조체(C/C++)와 자바의Point
VO는 동일하게 x, y 좌표를 나타내며, 여러 값을 하나로 묶는 점에서 공통점이 있다.
2.2 불변성(Immutable Object vs Const Struct)
자바의 VO는 주로 불변 객체로 사용된다. C/C++에서는 불변성을 보장하기 위해 구조체 멤버들을
const
로 선언할 수 있다. 이는 자바에서 필드를final
로 선언하는 것과 유사하다.struct Point { const int x; const int y; }; struct Point createPoint(int x, int y) { struct Point p = {x, y}; return p; }
2.3 동등성 비교
자바 VO에서 값 동등성은
equals()
와hashCode()
를 통해 구현된다. C/C++ 구조체에서 두 구조체의 동등성을 비교할 때는 각각의 필드 값을 비교하는 방식으로 동작한다.struct Point { int x; int y; }; int isEqual(struct Point p1, struct Point p2) { return (p1.x == p2.x && p1.y == p2.y); }
자바 VO의 동등성 비교 방식과 C/C++의 구조체의 값 비교 방식은 그 목적이 동일하며, 값 그 자체가 중요한 역할을 한다.
3. 차이점
3.1 행위 포함 여부
자바의 VO는 필요에 따라 일부 행위(메서드)를 포함할 수 있다. 예를 들어, 좌표 간의 거리 계산과 같은 간단한 로직은 VO에 포함될 수 있다. 반면, C의 구조체는 메서드를 포함할 수 없고, C++의 구조체는 메서드를 포함할 수 있지만 기본적으로 구조체는 데이터 묶음으로 사용된다.
자바:
public double distanceTo(Point other) { return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2)); }
C:
double distanceTo(struct Point p1, struct Point p2) { return sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2)); }
3.2 캡슐화와 정보 은닉
- 자바 VO는 데이터의 캡슐화와 정보 은닉을 지원한다. 필드를
private
으로 선언하고, getter 메서드를 통해서만 데이터에 접근할 수 있도록 하는 방식이 자바 VO의 일반적인 패턴이다. - 반면, C의 구조체는 캡슐화 개념이 없으며, 모든 필드가 기본적으로
public
처럼 동작한다. 즉, 구조체 멤버는 외부에서 직접 접근이 가능하다.
3.3 메모리 관리
- C/C++ 구조체는 스택 또는 힙에 할당될 수 있으며, 메모리를 직접 관리해야 한다. 반면, 자바 VO는 자동으로 가비지 컬렉션(Garbage Collection)을 통해 메모리 관리가 된다. 이는 구조체와 자바 VO 간의 큰 차이점이다.
3.4 생성자
- 자바 VO는 명시적인 생성자를 통해 객체를 생성할 수 있으며, 그 과정에서 불변성을 보장하기 위한
final
필드를 초기화할 수 있다. 반면에 C 구조체는 생성자 개념이 없고, 값을 직접 할당해야 한다.
결론
C/C++의 구조체와 자바의 Value Object(VO)는 여러 값들을 하나로 묶어 상태를 표현하는데 주로 사용되며, 데이터 중심의 객체라는 공통된 목표를 가진다. 둘 다 값을 기반으로 동등성을 판단하고, 값 자체에 초점을 맞춘다는 점에서 비슷하다. 그러나 자바 VO는 캡슐화, 불변성 등을 통해 더 객체 지향적인 특성을 가지고 있으며, 더 복잡한 동작을 포함할 수 있다.
따라서 C/C++ 구조체는 자바의 VO와 유사한 역할을 하면서도, 자바 VO와 달리 기본적인 캡슐화 및 메서드 지원 기능이 없다는 점에서 차이가 있다.
'Clang' 카테고리의 다른 글
[크래프톤 정글] malloc, calloc, realloc (0) | 2024.10.07 |
---|---|
[크래프톤 정글 ] 포인터 (0) | 2024.10.05 |