본문 바로가기
프로그래밍 C++

[c++] 24-08-30 공부 정리

by st-og 2024. 8. 30.

가변 인자

  • 함수나 템플릿 등에 인자의 개수를 정해두지 않고 가변적으로 사용
  • …를 사용

ex)

#include <iostream>
#include <string>

void Type1(std::string msg, int no, double value){
    std::cout << msg << no << value << std::endl;
}

void Type2(int no, double value){
    std::cout << no << value << std::endl;
}

template<typename... T>
void Printlog(T... arg0){
    Type1(arg0...);
    // Type2(arg0...);
    
}

int main(){
    Printlog<std::string, int, double>("Warning", 100, 22.5);
    // Printlog<int, double>(101, 55.6);
    return 0;
}

가변 인자 활용

  • va_list : 인자로 들어온 값들을 리스트로 처리
  • va_start(가변인자리스트, 가변인자개수): 리스트의 포인터 변수가 첫 번째 인자를 가리키도록 초기화
  • va_arg(리스트, 인자 타입): 현재 포인터 위치의 인자를 읽고 포인터를 다음으로 이동
  • va_end(리스트) : 가변 인자를 다 읽은 후 사용해야 함, 관례

ex)

#include <iostream>
#include <stdarg.h>

int Sum(int arg, ...){
    va_list ap;
    va_start(ap, arg);

    int sum = 0;

    for(int i=0; i < arg; i++){
        sum += va_arg(ap,int);
    }

    va_end(ap);

    return sum;
}

int main(){
    int number = Sum(5,1,2,3,4,5);

    std::cout << number << std::endl;

    return 0;
}

인라인 함수

  • 함수의 크기가 작고 여러번 호출 되는 경우 유용하게 사용 가능
  • 일반적인 함수 호출이 아닌 함수의 코드를 그대로 메인에서 사용하는 것과 비슷한 개념으로 동작
  • 함수 호출 과정을 생략가능해서 속도 빠름, 잘못 사용하면 프로그램 크기가 커짐

ex)

#include <iostream>

inline int Max(int x, int y){
    return x > y? x: y;
}

int main(){
    for (int i = 0; i < 5; i++){
        std::cout << Max(i, i+10) <<std::endl;
    }

    return 0;
}

예외처리

  • try catch를 사용해서 예외 처리

ex)

#include <iostream>
#include <vector>

int main(){
    std::vector<int> data;
    int number = 0;

    try{
        number= data.at(10);
    }

    catch (std::exception e) {
        std::cout << e.what() << std::endl;
    }

    return 0;
}

예외처리 응용

  • throw를 통해 예외를 던질 수 있음
  • 여러 예외를 생성 가능

ex)

#include <iostream>
#include <vector>

int main(){
    std::vector<int> data;
    data.push_back(1);

    try{
        if(data.empty() ==true){
            throw "empty";
        }

        if(data.size() <2) {
            throw 99;
        }

    }
    catch (char* e){
        std::cout << "char e" << e <<std::endl;
    }
    catch (int e){
        std::cout << "int e" << e << std::endl;
    }

    return 0;
}

사용자 정의 에러

  • 새로운 에러를 만들고 예외 처리를 할 수 있음
  • std::runtime_error 를 상속받은 클래스로 새로운 에러 처리 가능

ex)

#include <iostream>
#include <vector>
#include <string>

class InputError : public std::runtime_error{
    public:
        InputError(int idx, std::string msg) : runtime_error(""){
            std::cout << idx << msg << std::endl;
        }
};

int main(){
    std::vector<int>data;
    data.push_back(1);

    int idx=10;
    int value=20;

    try{
        if(idx >= data.size()){
            throw InputError(idx, std::to_string(value));
            data.at(idx) = 99;
        }
    }
    catch(InputError e){
            std::cout << e.what();
    }
    return 0;
}

Thread

  • join : 해당 스레드가 완전히 종료될 때까지 기다려 줌

ex)

#include <iostream>
#include <thread>
#include <chrono>

void Pause(int sec){
    std::this_thread::sleep_for(std::chrono::seconds(sec));
}

int main(){
    std::thread sleep1(Pause, 3);
    std::thread sleep2(Pause, 4);
    std::thread sleep3(Pause, 5);
    
    sleep1.join();
    std::cout << "3초 대기" << std::endl;

    sleep2.join();
    std::cout << "4초 대기" << std::endl;

    sleep3.join();
    std::cout << "5초 대기" << std::endl;

    return 0;

}

//만약 join이 없다면 main 함수에서는 더 이상 동작할 코드가 없으므로 
//다른 스레드의 동작이 마무리 되기 전에 프로그램이 종료 되버림
  • detach: 메인스레드에서 분리해서 독립적으로 실행되는 스레드
    • 점유한 자원의 반환이 보증됨
    • 제어가 불가능하기에 언제 어떻게 종료될지 모름

ex)

#include <iostream>
#include <thread>
#include <chrono>

void Pause(int sec){
    std::this_thread::sleep_for(std::chrono::seconds(sec));
    std::cout << sec<< " 초 대기" <<std::endl;
}

int main(){
    std::thread sleep1(Pause, 3);
    std::thread sleep2(Pause, 4);
    std::thread sleep3(Pause, 5);

    sleep1.detach();
    sleep2.detach();
    sleep3.detach();

    getchar();

    return 0;
}

'프로그래밍 C++' 카테고리의 다른 글

[c++] 24-08-29 공부 정리  (0) 2024.08.29
[C++] 24-08-28 공부 정리  (0) 2024.08.28