이번 글에서는 C++에서 클래스의 상속을 방지하는 방법에 대해 알아보겠습니다. 이처럼 더 이상 상속받지 못하도록 설계된 클래스를 final 클래스라고 부릅니다.C++에는 final 문법이 없다?Java나 C#에서는 final(또는 sealed) 키워드를 사용해 클래스의 상속을 손쉽게 차단할 수 있습니다. 하지만 C++에는 이를 위한 직접적인 언어 기능이 제공되지 않습니다. 그렇다면 어떻게 해야 할까요? 이번 글에서는 C++의 문법적 특성을 활용해 final 클래스를 흉내 내는(simulate) 기법을 살펴봅니다.핵심 아이디어: Ma
이 글에서는 GCC(GNU C Compiler)를 사용하여 C++ 프로그램을 컴파일하는 방법을 알아보겠습니다. 다음과 같은 간단한 C++ 프로그램을 컴파일한다고 가정해 보겠습니다.예제 코드#include<iostream> using namespace std; main() { cout << "Hello World. This is C++ program" << endl; }만약 이것이 C 프로그램이라면, 아래와 같이 GCC로 간단히 컴파일할 수 있습니다.gcc te
리눅스 환경에서 개발을 하다 보면 gcc와 g++ 컴파일러를 상황에 따라 번갈아 사용하게 됩니다. 두 컴파일러는 이름이 비슷해 같은 도구처럼 느껴지지만, 실제로는 몇 가지 중요한 차이점이 있습니다. 이번 글에서는 gcc와 g++의 차이를 자세히 살펴보겠습니다.GCC와 G++란?gcc는 GNU 프로젝트에서 제공하는 C 컴파일러이고, g++는 GNU C++ 컴파일러입니다. 참고로 초기의 GCC는 GNU C Compiler를 의미했지만, 현재는 다양한 언어를 지원하는 GNU Compiler Collection이라는 이름으로 불립니다.gc
열거형(Enumeration)은 C/C++ 언어에서 사용자가 직접 정의할 수 있는 데이터 타입입니다. 정수 상수들에 의미 있는 이름을 부여함으로써 프로그램의 가독성과 유지보수성을 크게 향상시킬 수 있습니다. 열거형은 enum 키워드를 사용하여 선언합니다. 열거형의 기본 문법 열거형을 선언하는 기본 문법은 다음과 같습니다. enum enum_name{const1, const2, ....... }; enum_name: 사용자가 임의로 지정하는 열거형의 이름입니다. const1, const2: 열거형 멤버에 해당하는 상수 값들입니다. e
C++ 소멸자(destructor)와 free() 함수의 차이 C++에서 소멸자(destructor)와 free() 함수는 모두 객체나 메모리와 관련이 있어 비슷해 보이지만, 실제 역할과 동작 방식은 완전히 다릅니다. 이 글에서는 두 개념의 차이점을 예제 코드와 함께 자세히 살펴보겠습니다. 소멸자(destructor)란 무엇인가? 소멸자는 객체가 소멸되기 직전에 자동으로 호출되는 특수한 멤버 함수입니다. 소멸자에서 수행하는 작업이 반드시 메모리 해제일 필요는 없으며, 화면에 메시지를 출력하는 것처럼 단순한 동작일 수도 있습니다.
C++에서 전역 변수(global variable)를 선언하려면 프로그램이 시작된 이후, 즉 어떤 함수나 블록 내부가 아닌 함수 외부 영역에 변수를 선언하면 됩니다. 전역 변수는 프로그램 전체에서 접근할 수 있어 여러 함수 간에 데이터를 공유할 때 유용합니다.전역 변수의 기본 개념전역 변수는 모든 함수의 바깥쪽, 즉 파일 스코프(file scope)에 선언됩니다. 이렇게 선언된 변수는 프로그램이 종료될 때까지 메모리에 유지되며, 코드 어디에서든 접근이 가능합니다.다른 파일에 전역 변수 선언하기만약 전역 변수를 별도의 파일에 저장하고
C++ 프로젝트가 커지면 코드를 여러 개의 소스 파일로 나누어 관리하는 것이 일반적입니다. 이 글에서는 여러 개의 .cpp 파일을 한 번에 컴파일하여 하나의 실행 파일로 만드는 방법을 알아보겠습니다. 방법은 매우 간단합니다. g++ 컴파일러에 파일 이름들을 목록 형태로 전달하기만 하면 됩니다.기본 컴파일 문법예를 들어 abc.cpp와 xyz.cpp 두 파일을 동시에 컴파일하려면 다음과 같은 명령어를 사용합니다.g++ abc.cpp xyz.cpp컴파일이 완료되면 기본적으로 a.out이라는 실행 파일이 생성되며, 다음 명령어로 프로그램
C 언어와 C++에는 모두 sprintf() 함수가 존재합니다. 이 함수는 다양한 데이터를 하나의 문자열 안에 저장하는 데 사용됩니다. 사용 문법은 printf() 함수와 거의 동일하지만, 유일한 차이점은 결과를 저장할 문자열 버퍼를 직접 지정해야 한다는 점입니다.C++에서는 ostringstream(출력 문자열 스트림)을 사용하여 동일한 작업을 더 안전하고 편리하게 수행할 수 있습니다. ostringstream은 <sstream> 헤더 파일에 정의되어 있으며, 숫자나 실수 등 다양한 타입의 데이터를 자동으로 문자열로 변
C++와 Java는 모두 객체 지향 프로그래밍의 핵심 개념인 상속(Inheritance)을 지원합니다. 상속은 기존 코드를 재사용하고 두 객체 사이에 계층적 관계를 형성하는 데 활용되는 강력한 기능입니다. 하지만 두 언어가 상속을 구현하고 처리하는 방식에는 몇 가지 중요한 차이점이 존재합니다. 이 글에서는 C++와 Java의 상속 메커니즘을 비교하며 그 차이점을 자세히 살펴보겠습니다. 1. Java의 모든 클래스는 Object 클래스를 상속받습니다 Java에서는 모든 클래스가 암묵적으로 Object 클래스를 확장(extends)합
C++과 Java에는 모두 static(정적) 키워드가 존재하며, 두 언어에서의 역할은 상당히 유사하지만 몇 가지 근본적인 차이점이 있습니다. 이 글에서는 C++의 static과 Java의 static이 어떻게 다른지 코드 예제를 통해 자세히 살펴보겠습니다. 1. 정적 데이터 멤버 (Static Data Member) 정적 데이터 멤버는 Java와 C++에서 기본적으로 동일하게 동작합니다. 정적 데이터 멤버는 클래스에 속한 속성이며, 해당 클래스로 생성된 모든 객체가 하나의 값을 공유한다는 점이 특징입니다. Java 예제 publi
함수에서 여러 값을 반환하는 방법 C나 C++에서는 기본적으로 함수가 한 번에 하나의 값만 반환할 수 있습니다. 여러 값을 반환해야 할 때 예전에는 포인터나 참조를 이용한 출력 매개변수(output parameter)를 함께 넘겨야 했지만, C++에서는 STL이 제공하는 튜플(tuple)과 페어(pair)를 활용하면 훨씬 깔끔하게 해결할 수 있습니다. 튜플(Tuple)과 페어(Pair)란? 튜플(tuple)은 여러 개의 요소를 하나로 묶어 담을 수 있는 객체입니다. 각 요소는 서로 다른 타입이어도 되며, 담을 수 있는 값의 개수에
final 클래스란? Java나 C#에서는 final 클래스를 사용할 수 있습니다. final 클래스는 더 이상 다른 클래스가 상속(확장)할 수 없도록 봉인된 특수한 형태의 클래스입니다. 하지만 C++에는 이런 기능을 직접 지원하는 문법이 없기 때문에, 몇 가지 기법을 조합해 final 클래스의 동작을 흉내 내야 합니다. 시뮬레이션의 핵심 원리 아이디어는 간단합니다. MakeFinalClass라는 보조 클래스를 하나 추가로 만들고, 이 클래스의 기본 생성자를 private으로 선언하는 것입니다. 생성자가 private이면 외부 코드
이 글에서는 C++에서 explicit 키워드가 어떤 영향을 미치는지 자세히 알아보겠습니다. 본격적인 설명에 앞서, 먼저 예제 코드를 살펴보고 출력 결과를 예측해 보겠습니다.예제 1: explicit 키워드 없이 작성한 코드#include <iostream> using namespace std; class Point { private: double x, y; public: Point(double a = 0.0, double b = 0.0) : x(a), y(b) {
C++에서 클래스의 소멸자(destructor)를 private 멤버로 선언하면 어떤 일이 일어날까요? 이 글에서는 여러 예제 코드를 통해 프라이빗 소멸자가 컴파일 과정과 객체의 생성·소멸에 어떤 영향을 미치는지 단계별로 살펴보겠습니다.1. 객체를 생성하지 않는 경우다음 코드에는 private 소멸자가 정의되어 있지만, 실제 객체를 생성하지 않으므로 어떠한 오류도 발생하지 않습니다.예제 1#include <iostream> using namespace std; class my_class {  
C++에서는 이름은 같지만 서로 다른 버전의 함수를 정의하는 함수 오버로딩(Function Overloading)이 가능합니다. 흥미로운 점은 멤버 함수 뒤에 붙는 const 키워드도 오버로딩 구분 기준이 된다는 것입니다. 즉, 일반 함수와 상수(const) 타입의 함수를 같은 이름으로 공존시킬 수 있습니다.상수 함수와 일반 함수가 어떻게 구분되어 호출되는지, 아래 예제 프로그램과 출력 결과를 통해 자세히 알아보겠습니다.예제 1: 객체의 상수 여부에 따른 함수 호출#include <iostream> using namesp
C++는 함수 오버로딩(function overloading)을 지원하는 강력한 언어입니다. 그렇다면 자연스럽게 이런 의문이 생깁니다. 과연 프로그램의 진입점인 main() 함수도 오버로딩할 수 있을까요?먼저 main() 함수를 오버로딩하려고 시도하는 코드를 직접 확인해 보겠습니다.예제 1: main() 오버로딩 시도#include <iostream> using namespace std; int main(int x) { cout << Value of x: <&l
C++에서는 이미 정의된 네임스페이스를 나중에 다시 열어 멤버를 추가하는 방식으로 네임스페이스를 확장할 수 있으며, 이름이 없는 무명(익명) 네임스페이스를 사용하여 파일 내부에서만 접근 가능한 고유한 식별자를 선언할 수도 있습니다. 이번 글에서는 두 가지 기법을 예제와 함께 자세히 살펴보겠습니다.네임스페이스 확장이란?하나의 네임스페이스는 여러 번에 걸쳐 정의될 수 있습니다. 같은 이름의 네임스페이스 블록을 반복해서 작성하면, 컴파일러는 이들을 하나로 합쳐서 관리합니다. 첫 번째 정의에 어떤 멤버가 있고, 두 번째 정의에 다른 멤버가
C++에서 friend(우정) 관계는 상속되지 않습니다. 즉, 부모 클래스에 friend 함수가 선언되어 있더라도, 그 클래스를 상속받은 자식 클래스에게는 해당 friend 권한이 자동으로 전달되지 않습니다.다음 예제는 이러한 동작을 보여줍니다. display() 함수는 MyBaseClass의 friend로 선언되어 기반 클래스의 멤버에는 접근할 수 있지만, MyDerivedClass의 friend가 아니기 때문에 파생 클래스의 private 멤버에는 접근할 수 없으며, 이로 인해 컴파일 오류가 발생합니다.예제 코드#include
C++에서는 함수 오버로딩(function overloading)을 통해 이름은 같지만 매개변수 구성이 다른 여러 함수를 정의할 수 있습니다. 그런데 기본 클래스(base class)에 오버로드된 형태의 메서드가 존재하고, 파생 클래스(derived class)에서 그중 하나만 재정의하면 예상치 못한 문제가 발생합니다.바로 파생 클래스에서 해당 함수 이름으로 접근할 때, 기본 클래스에 정의되어 있던 모든 오버로드 버전이 함께 가려지는(name hiding) 현상입니다.왜 이런 현상이 발생할까?C++의 이름 조회(name lookup
이 글에서는 C++에서 사용할 수 있는 fesetround()와 fegetround() 함수에 대해 알아봅니다. 두 함수 모두 <cfenv> 헤더에 포함되어 있으며, 부동소수점 연산의 반올림 방향을 설정하거나 확인하는 데 사용됩니다.fesetround() 함수란?fesetround() 함수는 지정한 부동소수점 반올림 방향을 현재 반올림 방향으로 설정하는 역할을 합니다. 이 함수는 C++의 rint(), nearbyint() 등 다양한 반올림 함수들과 함께 사용되며, 반올림 동작을 세밀하게 제어할 수 있게 해줍니다.함수의