#define #include #ifdef #ifndef
#include 는 현재 프로그래밍에서는 대체할 수는 있는 수단이 없고
#ifdef #ifndef은 매우 유용하게 사용하는 수단입니다.
하지만, #define은 const, enum, inline 등등 매우 유용하게 쓰일 수 있는 수단이 있습니다.
즉 선행 처리자보다 컴파일러를 가까이 하자는 의미인데요.
예를 들자면 #define PI = 3.14라고 한다면
선행 처리자가 PI라고 작성된 소스코드를 모두 3.14로 선행 처리가 됩니다.
만약 이 부분에서 컴파일 오류나 논리 오류가 발생한다면?
3.14라는 상수에서 오류가 검출이 되고 찾기 어렵겠죠?
심지어 private 성격을 가지는 #define은 없습니다.
const를 사용하자
#define PI 3.14 대신에
const double PI 3.14 를 사용해봅시다.
매크로 같은 경우는 코드에 PI가 등장하기만 하면 선행 처리자에 의해 3.14로 모두 바뀌면서 결국 목적 코드 안에 3.14의 사본이 등장 횟수 만큼 들어가게 됩니다.
하지만, const를 사용하게 되면 아무리 여러 번 쓰이더라도 사본은 딱 한 개만 생기게 됩니다.
주의할 점으로는 상수 포인터를 사용할 때 입니다.
1 2 3 4 5 6 7 8 9 10 11 12 | #include<iostream> // #define -> const const char* const userName = "rojae"; const std::string txt("hihi"); int main(){ std::cout << "UserName :" << userName << '\n' << "Message :" << txt << '\n'; return 0; } | cs |
char* const userName = "rojae" 일 경우
const char* const userName = "rojae"로 바꾸어 주면 됩니다.
하지만 C++에서는 char 형 문자열보다는 std::string을 쓰기 때문에
(구닥다리는 버립시다)
다음과 같이 정의하는 것이 이롭습니다.
const std::string userName("rojae")
클래스 내부에 상수 선언
클래스 내부 상수를 선언하는 경우에는 static을 사용하여
캡슐화도 만족하게 되며 번거롭게 메모리가 복사되는 일은 없게 됩니다.
책보고 대충 작성했는데...
올바르게 한지는 모르겠네요.
player.hpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include<vector> #include<iostream> class Player{ private: static const int maxUser = 10; std::vector<int> score; public: void insertScore(int &v){ if(score.size() > maxUser-1){ std::cout << "Max player" << '\n'; return; } score.push_back(v); } void getAllScore(){ std::cout << "Current Player :" << score.size() << '\n'; for(int i = 0; i < score.size(); i++){ std::cout << score[i] << '\n'; } } }; | cs |
player.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <iostream> #include "player.hpp" int main(){ int n; std::cout << "how many player?" << '\n'; std::cin >> n; Player player; for(int i = 0; i < n; i++){ std::cout << "Insert Player scores :" << '\n'; int score; std::cin >> score; player.insertScore(score); } player.getAllScore(); return 0; } | cs |
# 컴파일러마다 문법이 먹히지 않는 경우가 있는데 그런 경우에는 다음과 같이 분리합니다.
static const int maxUser; // 선언 헤더 파일
const int player::maxUser = 10; // 구현 파일
enum을 사용한 enum hack
1 | enum {maxUser = 10}; | cs |
1 2 3 4 | int a = 5, b = 0; CALL_WITH_MAX(++a, b); CALL_WITH_MAX(++a, b+10); | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include<iostream> template<typename T> inline T callWithMax(const T& a, const T& b); int main(){ int a = 5, b = 0; std::cout << "Max :" << callWithMax(a,b) << '\n'; std::cout << "Max :" << callWithMax(5.1, 0.1) << '\n'; std::cout << a << b; return 0; } template<typename T> inline T callWithMax(const T& a, const T& b){ return (a > b)? a : b; } | cs |
마무리
※ 본 글은 개인 포트폴리오 혹은 공부용으로 사용하기 때문에, 무단 복사 유포는 금지하지만, 개인 공부 용도로는 얼마든지 사용하셔도 좋습니다
'C_C++ 프로그래밍 > Effective C++' 카테고리의 다른 글
[Effective C++] 5. C++이 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 (0) | 2019.09.05 |
---|---|
[Effective C++] 4. 객체를 사용하기 전에 반드시 객체를 초기화하자 (0) | 2019.09.03 |
[Effective C++] 3. 낌새만 보이면 const를 들이대 보자! (0) | 2019.08.29 |
[Effective C++] 1. C++를 언어들의 연합체로 바라보는 안목은 필수 (0) | 2019.08.26 |
댓글