C:\Users\KDT107\Desktop\learn_cpp\init_folder\cpp_source>g++ -o RacingCar.cpp Car.cpp
틈틈히 C++ 를 공부해놔야할 것 같아 정리하는 문서입니다.
교재는 『윤성우의 C++ 열혈프로그래밍』를 사용하였고, 예제를 통해 실습 진행해보았습니다.
환경설정은 기존에 C언어를 공부하면서 설치했던 MinGw를 이용했습니다.
(MinGw에 C언어, C++언어 컴파일러 둘 다 탑재하고 있음)

기존에 해놓은게 있어서, 환경변수를 따로 건드린 것은 없었습니다.
또한, vscode 를 오랜만에 쓰려니, 단축키가 계속 헷갈려서 intellij keymap을 extension으로 설치하였습니다.
(Pycharm의 제작회사가 Intellij임)

살짝 다른 부분들이 있지만, 그래도 대부분(70~80%) 정도는 지원해주는 것 같아 큰 불편함 없이 적응했습니다.
포인터와 구조체 사용방법은 아직 완벽하게는 아니지만, 어느정도 숙지하고 책의 예제를 따라쳐보면서, 익숙해지는 시간을 가졌습니다.
C언어에서는 구조체에서 Attribute만 사용할 수 있는 불완전한 상태였는데,
C++로 넘어오면서, class가 사용가능해지고, 함수도 선언가능해졌습니다.
또한, Python에서는 "from somefilename import ClassName" 면 쉽게 다른 파일의 클래스를 사용할 수 있었지만,
C++로 들어오면서는 헤더파일의 이해와, #ifndef, #define, #endif, namespace의 개념에 대해 이해가 필요했습니다.
책에서 선언한 Car class 입니다.
/* Car.h */
#ifndef __CAR_H__
#define __CAR_H__
namespace CAR_CONST {
enum {
ID_LEN = 20,
MAX_SPD = 200,
FUEL_STEP = 2,
ACC_STEP = 10,
BRK_STEP = 10
};
}
class Car {
private:
char gamerID[CAR_CONST::ID_LEN];
int fuelGuage;
int curSpeed;
public:
void InitMembers(char* ID, int fuel);
void ShowCarState();
void Accel();
void Break();
};
#endif
/* Car.cpp */
#include "Car.h"
#include <cstring>
#include <iostream>
using namespace std;
void Car::InitMembers(char* ID, int fuel) {
strcpy(gamerID, ID);
fuelGuage = fuel;
curSpeed = 0;
}
void Car::ShowCarState() {
cout << "소유자ID: " << gamerID << endl;
cout << "연료량: " << fuelGuage << "%" << endl;
cout << "현재 속도: " << curSpeed << "km/s" << endl;
}
void Car::Accel() {
if (fuelGuage <= 0) {
return;
} else {
fuelGuage -= CAR_CONST::FUEL_STEP;
}
if (curSpeed + CAR_CONST::ACC_STEP >= CAR_CONST::MAX_SPD) {
curSpeed = CAR_CONST::MAX_SPD;
return;
}
curSpeed += CAR_CONST::ACC_STEP;
}
void Car::Break() {
if (curSpeed < CAR_CONST::BRK_STEP) {
curSpeed = 0;
return;
}
curSpeed -= CAR_CONST::BRK_STEP;
}
/* RacingMain.cpp */
#include "Car.h"
int main() {
Car run99;
run99.InitMembers("run99", 100);
run99.Accel();
run99.Accel();
run99.Accel();
run99.ShowCarState();
run99.Break();
run99.ShowCarState();
return 0;
}
이렇게 작성하고 Build 를 실행했더니 다음과 같은 오류를 만났다.
Car.cpp 에서 세부적으로 선언한 함수들이 다 undefined 처리가 되었다.
빌드를 시작하는 중...
"C:\Program Files\mingw64\bin\g++.exe" -fdiagnostics-color=always -g C:\Users\KDT107\Desktop\learn_cpp\init_folder\cpp_source\RacingMain.cpp -o C:\Users\KDT107\Desktop\learn_cpp\init_folder\cpp_source\rooster.exe
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\KDT107\AppData\Local\Temp\ccrwiMAk.o: in function `main':
C:/Users/KDT107/Desktop/learn_cpp/init_folder/cpp_source/RacingMain.cpp:6: undefined reference to `Car::InitMembers(char const*, int)'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/KDT107/Desktop/learn_cpp/init_folder/cpp_source/RacingMain.cpp:7: undefined reference to `Car::Accel()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/KDT107/Desktop/learn_cpp/init_folder/cpp_source/RacingMain.cpp:8: undefined reference to `Car::Accel()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/KDT107/Desktop/learn_cpp/init_folder/cpp_source/RacingMain.cpp:9: undefined reference to `Car::Accel()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/KDT107/Desktop/learn_cpp/init_folder/cpp_source/RacingMain.cpp:10: undefined reference to `Car::ShowCarState()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/KDT107/Desktop/learn_cpp/init_folder/cpp_source/RacingMain.cpp:11: undefined reference to `Car::Break()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/KDT107/Desktop/learn_cpp/init_folder/cpp_source/RacingMain.cpp:12: undefined reference to `Car::ShowCarState()'
collect2.exe: error: ld returned 1 exit status
빌드가 완료되었지만, 오류가 발생했습니다.
원인을 찾아보니 g++로 컴파일 할 때 다음과 같이 터미널에 작성해줘야한다는 것이다.
C:\Users\KDT107\Desktop\learn_cpp\init_folder\cpp_source>g++ -o Car.cpp RacingCar.cpp
그런데 실수로 순서를 바꿔서 넣었더니..
C:\Users\KDT107\Desktop\learn_cpp\init_folder\cpp_source>g++ -o Car.cpp RacingMain.cpp
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\KDT107\AppData\Local\Temp\ccao3DhY.o:RacingMain.cpp:(.text+0x22): undefined reference to `Car::InitMembers(char const*, int)'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\KDT107\AppData\Local\Temp\ccao3DhY.o:RacingMain.cpp:(.text+0x2e): undefined reference to `Car::Accel()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\KDT107\AppData\Local\Temp\ccao3DhY.o:RacingMain.cpp:(.text+0x3a): undefined reference to `Car::Accel()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\KDT107\AppData\Local\Temp\ccao3DhY.o:RacingMain.cpp:(.text+0x46): undefined reference to `Car::Accel()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\KDT107\AppData\Local\Temp\ccao3DhY.o:RacingMain.cpp:(.text+0x52): undefined reference to `Car::ShowCarState()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\KDT107\AppData\Local\Temp\ccao3DhY.o:RacingMain.cpp:(.text+0x5e): undefined reference to `Car::Break()'
c:/program files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\KDT107\AppData\Local\Temp\ccao3DhY.o:RacingMain.cpp:(.text+0x6a): undefined reference to `Car::ShowCarState()'
collect2.exe: error: ld returned 1 exit status
또 undefined 에러가 나왔다.
어떤 것을 먼저 참조시키느냐가 순서가 중요해진다는 걸 알았다...
순서를 옳게 했더니 잘 compile 되었다.
하지만, 터미널에서 매번 입력하는 것보단 vscode 에서 ctrl + F5 로 run 하고 싶었다.
방법을 찾아보니 StackOverFlow에 비슷한 상황이 있었다.
VSCode compile C++ with external classes - undefined reference to `MyClass::MyClass()'
Error when compiling my main file & external Class file using VScode. file structure: project/ --main.cpp --MyClass.cpp --MyClass.h MyClass.h #ifndef MY_CLASS_H #define MY_CLASS_H class My...
stackoverflow.com
#include "Car.cpp"
#include "Car.h"
int main() {
Car run99;
run99.InitMembers("run99", 100);
run99.Accel();
run99.Accel();
run99.Accel();
run99.ShowCarState();
run99.Break();
run99.ShowCarState();
return 0;
}
#include 에 참조가 필요한 cpp file을 추가해줌으로써 추가 terminal command를 작성할 필요 없이 run이 정상적으로 되었다.
소유자ID: run99
연료량: 94%
현재 속도: 30km/s
소유자ID: run99
연료량: 94%
현재 속도: 20km/s
또한, 개발 중간에

C:\Users\KDT107\Desktop\learn_cpp\init_folder\cpp_source\RacingMain.cpp:6:23: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
6 | run99.InitMembers("run99", 100);
| ^~~~~~~
빌드가 완료되었지만, 경고가 발생했습니다.
* 터미널이 작업에서 다시 사용됩니다. 닫으려면 아무 키나 누르세요.
이런 경고가 발생했었는데, 원인은 Cpp 의 char * -> const char * 로 선언이 필요했다.
StackOverFlow에 확인해보니,
Why is conversion from string constant to 'char*' valid in C but invalid in C++
The C++11 Standard (ISO/IEC 14882:2011) says in § C.1.1: char* p = "abc"; // valid in C, invalid in C++ For the C++ it's OK as a pointer to a String Literal is harmful since any attempt to modify...
stackoverflow.com
기존에는 암시적으로 const char* 로 바꾸는 작업을 해줬는데, C++ 11버전으로 바뀌면서, 직접 형변환을 하지 않으면 경고를 날리게 되었다고 한다. 기존의 코드들은 작동하게끔 유지해야할 필요가 있어서 build는 되지만 안전하게 string을 parameter로 사용할 경우엔 const char* 를 사용하도록 한다.
Python class 에서 Cpp class를 선언해보는 과정을 겪어보았는데, 확실히 python에서 parameter에 제한이 없는 상태로 코딩하다가, 보다 엄격한 문법 규칙을 준수하다보니, 답답함과 뭔가 생산성의 저하..? 가 느껴졌다.
하지만, 그만큼 파이썬에서 이런 일련의 과정을 내부적으로 하고 있던 일이고, Python으로 prototype을 제작하고, Cpp로 본격 개발을 하는 경우가 많다고 하니, 두 언어 모두 결과적으로 숙련되어야할 숙명이라 생각한다.
틈틈히 Cpp 개발을 공부하여 익숙해져보도록 노력할 예정이다.
감사합니다.
'언어 > C or C++' 카테고리의 다른 글
C언어 한글 입력 받기 실패 & 배열 없이 로또 번호 생성, 정렬 [2023-03-30 학습일지] (1) | 2023.05.28 |
---|---|
C 언어로 한글 파일 출력하기 [2023-03-29 학습일지] (0) | 2023.05.28 |
C언어 변수, 그런데 메모리를 곁들인 [2023-03-24 학습일지] (0) | 2023.05.28 |
C 언어 포인터 쉽게 이해해보려 노력하기 [2023-03-22 학습일지] (0) | 2023.05.28 |
C의 탄생 이전엔 어떤 프로그래밍 언어들이 있었을까? [2023-03-20 학습일지] (0) | 2023.05.28 |