#if, 초기화리스트, const, namespace
#if는 사전 처리기(preprocessor) 지시문입니다. 이는 컴파일 과정에서 소스 코드가 실제로 컴파일되기 전에 처리
일반 if 문은 실행 시간(runtime) 조건문입니다. 프로그램이 실행될 때 평가되고, 조건이 참이면 if 블록 내의 코드가 실행
차이가 있다.
---
#if 쓰는 이유 : 동작과정은 동일하나, 컴파일에 포함시키지 않아 프로그램의 크기를 줄일 수 있고 불필요한 조건 검사를 하지 않는다.
ex) 디버깅용도
하단의 코드는 if 조건에 해당하지 않더라도, 해당 코드는 컴파일되어 프로그램이 생성된다.
bool debugMode = false;
int main() {
if (debugMode) {
// 이 코드는 debugMode가 true일 때만 실행됩니다.
// 하지만 debugMode가 false라도 이 코드는 컴파일되어 프로그램에 포함됩니다.
printf("Debug mode is enabled.\n");
}
return 0;
}
하단의 코드는 if 조건에 해당하지 않으면, 해당 코드는 컴파일되지 않고 프로그램이 생성된다.
따라서 #if 지시문을 사용하면 최종 릴리스 버전의 컴파일 과정에서 이 코드가 완전히 제거되어 프로그램의 크기와 성능에 영향을 주지 않는다.
//#define DEBUG // 이 줄을 주석 처리하면 DEBUG는 정의되지 않습니다.
int main() {
#ifdef DEBUG
// DEBUG가 정의되어 있으면 이 코드 블록이 컴파일됩니다.
printf("Debug mode is enabled.\n");
#endif
return 0;
}
초기화 리스트
ex) class 를 부르는 형상에 따른 호출되는 생성자
#include<iostream>
#include<string>
using namespace std;
class Person {
private:
int age_;
string str_;
public:
Person() : age_(0), str_("BlockDMask")
{
cout << "디폴트 생성자 호출" << endl;
}
Person(int age, string str) : age_(age), str_(str)
{
cout << "age, str 생성자 호출" << endl;
}
Person& operator = (const Person& rsh)
{
this->age_ = rsh.age_;
this->str_ = rsh.str_;
cout << "대입 연산자 호출" << endl;
return *this;
}
void printAll() {
cout << "age : " << age_ << endl;
cout << "str : " << str_ << endl;
}
};
int main(void) {
// 클래스 같은 경우
cout << "\n=====\n";
Person p1(10, "aa"); // age, str 생성자 호출
p1.printAll();
cout << "\n\n=====\n";
Person p2 = { 20, "bb" }; // age, str 생성자 호출
p2.printAll();
cout << "\n\n=====\n";
Person p3 = Person(30, "cc"); // age, str 생성자 호출
p3.printAll();
cout << "\n\n=====\n";
Person p4; // 디폴트 생성자 호출
p4 = Person(40, "dd"); // age, str 생성자 호출, 대입 연산자 호출
p4.printAll();
int z;
cin >> z;
return 0;
}
// 출처: https://blockdmask.tistory.com/510 [개발자 지망생:티스토리]
ex) 초기화 리스트가 꼭 필요한 경우
- const 로 선언 된 경우
: const int age; 으로 선언 후 age = 100; 이런식으로 값 대입이 불가능
: 이 경우 초기화 리스트를 이용해 값 대입이 필요
class Person {
private:
const int age;
bool isMan;
public:
// 아래와 같이 멤버 초기화 리스트는 const 변수 가능
Person() : age(100), isMan(true)
{
//const 변수를 대입, 할당 하는것 이기 때문에 불가능
//age = 99; //error
//isMan = false; //ok
}
};
// 출처: https://blockdmask.tistory.com/510 [개발자 지망생:티스토리]
const
변수의 상수화 [ 초기 선언시, 값대입(메모리할당)이 같이 들어가야 함 ]
1. const 비-멤버 변수
const int num = 1; // num 값 변경 불가
2. const 멤버 변수
#include <iostream>
#include <string>
using namespace std;
class Monitor
{
const int bb; // 메모리 할당 전
public:
explicit Monitor() : bb(0) { // 메모리 할당 시기 ( const int bb 를 0으로 초기화 )
std::cout << "Monitor 생성자 호출" << std::endl;
}
~Monitor() {
std::cout << "Monitor 소멸자 호출" << std::endl;
}
string class_name = "Monitor_member_variable";
};
Monitor class_1() {
Monitor* addr_m = new Monitor;
Monitor& ref_m = *addr_m;
return ref_m;
}
3. const 포인터 변수
const int* ptr = # // *ptr을 상수화
int* const ptr = &num1; // ptr을 상수화
int num = 1;
const int* ptr = # // *ptr을 상수화
*ptr = 2; // Compile Error
num = 2; // Pass
int num1 = 1;
int num2 = 2;
int* const ptr = &num1; // ptr을 상수화
ptr = &num2; // Compile Error
4. const 멤버 함수 [ 상수 멤버 함수 ]
int GetNum(void) const
- 멤버 함수만 이런 식으로 사용 가능
- 의미 : 이 함수가 클래스의 상태를 변경하지 않음
: const 키워드가 붙은 멤버 함수 내에서는 객체의 멤버 변수를 변경이 불가
int GetString(void) const; // Compile Error
class Foo{
int num = 1;
int GetNum(void) const
{
int a = 1;
a++; // 지역 변수는 가능
num++; // Compile Error
return num;
}
};
namespace
namespace rosmon
{
namespace monitor
{
NodeMonitor::NodeMonitor(const launch::LaunchConfig::ConstPtr& config, const launch::Node::ConstPtr& launchNode, FDWatcher::Ptr fdWatcher, ros::NodeHandle& nh)
: m_launchConfig(config)