인사
안녕하세요.
이번 포스팅은 C++ 언어 A부터 Z까지 여섯 번째 시간입니다. 오늘은 클래스(Class)와 구조체(Struct)에 대해 추가적으로 공부한 내용을 정리하고자 합니다.
클래스
이번 포스팅에서는 C++에서 클래스(Class)를 사용하는 방법과 간단한 예제를 통해 클래스 개념을 정리해보려 합니다. 또한 클래스에 대한 개인적인 생각과 다른 언어와의 비교도 함께 소개하겠습니다.
#include <stdio.h>
#include <iostream>
class Calculus {
public:
Calculus(double a_, double b_) : a(a_), b(b_) {}
double Plus () {
return a + b;
}
double minus() {
return a - b;
}
double display() {
return a * b;
}
double divide() {
return a / b;
}
private:
double a;
double b;
};
int main(void) {
// a, b
double a, b;
std::cin >> a >> b;
getchar();
// calculus
Calculus c(a, b);
std::cout << a << "+" << b << "=" << c.Plus() << std::endl;
std::cout << a << "-" << b << "=" << c.minus() << std::endl;
std::cout << a << "*" << b << "=" << c.display() << std::endl;
if ( b == 0 ) std::cout << "no" << std::endl;
else std::cout << a << "/" << b << "=" << c.divide() << std::endl;
return 0;
}
클래스가 주는 매력
저는 개인적으로 여러 프로그래밍 언어 중에서도 클래스(Class)를 이용한 객체지향 프로그래밍을 가장 선호합니다. Python을 처음 배웠을 때도 클래스 개념이 쉽지는 않았지만, 가장 흥미롭게 느꼈던 기억이 있습니다.
함수를 하나의 객체 단위로 묶고 다룰 수 있다는 점은 개발자로서 코드의 구조를 명확하게 잡는 데에 큰 도움이 됩니다.
언어 간 클래스 구조의 유사성
Python, JavaScript, C++ 등 대부분의 언어에서 클래스 구조는 유사한 형태를 띠고 있습니다. 예를 들어 생성자(Constructor)를 이용한 초기화, 접근 제어자(public/private/protected), 상속 구조 등은 거의 동일한 흐름을 따릅니다.
C++ 또한 클래스 내부에 private 멤버를 선언하고, 생성자를 통해 public에서 초기화하는 방식으로 객체를 구성합니다. 외부에서는 public에 선언된 함수만 접근할 수 있기 때문에 캡슐화된 구조를 만들기에도 적합합니다.
아직은 어려운 개념 – 상속
한 가지 아쉬운 점은 C++에서의 상속 개념에 대해 아직은 익숙하지 않다는 것입니다. JavaScript나 Python에서는 super() 등을 이용해 손쉽게 부모 클래스를 호출할 수 있었지만, C++에서는 이러한 구조를 아직 잘 다뤄보지 못해 추가적인 학습이 필요하다고 느꼈습니다.
앞으로 상속이나 다형성 개념까지 익히게 된다면, 그 부분도 별도의 포스팅으로 정리해보겠습니다.
구조체
C++에서 struct는 단순히 데이터를 담는 역할을 넘어서, 함수를 함께 정의하여 객체처럼 활용할 수 있다는 장점이 있습니다. 특히 간단한 계산기와 같은 기능을 구현할 때 구조체를 이용하면 가독성 좋고 유기적인 코드를 만들 수 있습니다.
#include <stdio.h>
#include <iostream>
struct Calculus {
double a;
double b;
double Plus() {
return a + b;
}
double Minus() {
return a - b;
}
double Display() {
return a * b;
}
double Divide() {
return a / b;
}
};
int main(void) {
// a, b
int a, b;
std::cin >> a >> b;
struct Calculus c;
c.a = a;
c.b = b;
std::cout << a << "+" << b << "=" << c.Plus() << std::endl;
std::cout << a << "-" << b << "=" << c.Minus() << std::endl;
std::cout << a << "*" << b << "=" << c.Display() << std::endl;
if ( b == 0 ) std::cout << "no" << std::endl;
else std::cout << a << "-" << b << "=" << c.Divide() << std::endl;
return 0;
}
위 코드처럼 struct 내부에 함수를 선언함으로써 간단한 연산 로직을 구조적으로 관리할 수 있습니다. 이는 클래스(class)와 유사하며, 접근 지정자 기본값만 다를 뿐 C++에서는 거의 동일한 방식으로 활용 가능합니다.
💡 참고: Go(Golang)에서도 struct 사용
Go 언어에서도 struct를 기반으로 비슷한 방식의 기능 구현이 가능합니다. 다만 함수 정의 방식이나 에러 처리가 C++과는 다릅니다. 아래는 간단한 참고용 코드입니다:
package main
import (
"errors"
"fmt"
)
type Calculus struct {
a float64
b float64
}
func (c Calculus) Plus() float64 {
return c.a + c.b
}
func (c Calculus) Minus() float64 {
return c.a - c.b
}
func (c Calculus) Display() float64 {
return c.a * c.b
}
func (c Calculus) Divide() (float64, error) {
if c.b == 0 {
return 0.0, errors.New("no")
}
return c.a / c.b, nil
}
func main() {
var (
c Calculus
)
fmt.Scanf("%f %f", &c.a, &c.b)
fmt.Printf("%f + %f = %f\n", c.a, c.b, c.Plus())
fmt.Printf("%f - %f = %f\n", c.a, c.b, c.Minus())
fmt.Printf("%f * %f = %f\n", c.a, c.b, c.Display())
if value, err := c.Divide(); err != nil {
fmt.Println(err.Error())
} else {
fmt.Printf("%f / %f = %f\n", c.a, c.b, value)
}
}
Go에서는 위와 같이 메서드를 func (c StructName) MethodName() 형식으로 구조체에 연결할 수 있습니다.
※ 자세한 내용은 Go 공식 문서를 참고하세요.
정리
-
C++의 구조체는 데이터를 담는 것뿐 아니라 함수와 함께 정의하여 객체처럼 사용할 수 있는 강력한 기능을 제공합니다.
-
특히 간단한 도구나 계산기처럼 명확한 역할을 갖는 코드를 짤 때 유용합니다.
-
Go에서도 구조체를 비슷하게 활용할 수 있지만, 문법적 차이와 철학적 접근이 다릅니다.
마무리
오늘은 C++의 클래스(class)와 구조체(struct) 객체에 대해 소개해드렸습니다.
이 두 가지는 모두 매우 유용한 도구로, 함수를 비롯한 변수들을 객체 단위로 정리하고 관리할 수 있다는 점에서 큰 장점을 가지고 있습니다.
상황에 따라 클래스를 사용할지 구조체를 사용할지는 다를 수 있지만, 둘 다 코드를 체계적이고 효율적으로 작성하는 데 큰 도움이 됩니다.
그럼 오늘의 포스팅은 여기서 마치겠습니다.
항상 하시는 일들 잘되시길 바라며, 모두 화이팅입니다!