-
[Effective C++] 2. #define을 쓰려거든 const enum, inline을 떠올리자.C_C++ 프로그래밍/Effective C++ 2019. 8. 28. 00:27
#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를 사용하게 되면 아무리 여러 번 쓰이더라도 사본은 딱 한 개만 생기게 됩니다.
주의할 점으로는 상수 포인터를 사용할 때 입니다.
123456789101112#include<iostream>// #define -> constconst 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
123456789101112131415161718192021222324#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
123456789101112131415161718192021#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
사실 나열자 둔갑술이 제일 좋다고 합니다.위의 헤더파일의 maxUser 부분을다음과 같이 바꾸어 줍니다.1enum {maxUser = 10};cs 이 경우 주소 값도 가지지 않으며 참조자를 가지지 않습니다.위와 같은 매크로를 자주 경험해봤을 것입니다.다음 소스코드를 봅시다.1234int a = 5, b = 0;CALL_WITH_MAX(++a, b);CALL_WITH_MAX(++a, b+10);cs 실행해보면 놀랍지만두번째 줄에서 a는 2가 증가하며세번째 줄에서는 a가 1이 증가하게 됩니다.이를 해결하기 위해서 우리는 템플릿 inline 함수를 사용합니다.1234567891011121314151617#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