가변 인자
- 함수나 템플릿 등에 인자의 개수를 정해두지 않고 가변적으로 사용
- …를 사용
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 |