언어 정리/C++_개념_lib

#if, 초기화리스트, const, namespace

알 수 없는 사용자 2024. 1. 2. 18:14

 

 

#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 = &num; // *ptr을 상수화

int* const ptr = &num1; // ptr을 상수화

int num = 1;
const int* ptr = &num; // *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)