C++/Library 2021. 3. 24. 10:48

weak_ptr

weak_ptr

  • <memory> 라이브러리

  • shared_ptr의 순환 의존성 문제를 해결할 수 있다.

    #include <iostream>
    #include <memory>
    
    class Person
    {
      std::string            name_;
      std::weak_ptr<Person>    partner_;
    
    public:
      Person(const std::string& name) : name_(name)
      {
        std::cout << name_ << " created\n";
      }
    
      ~Person()
      {
        std::cout << name_ << " destroyed\n";
      }
    
      friend bool partnerUp(std::shared_ptr<Person>& p1, std::shared_ptr<Person>& p2)
      {
        if (!p1 || !p2)
          return false;
    
        p1->partner_ = p2;
        p2->partner_ = p1;
    
        std::cout << p1->name_ << " is partnered with " << p2->name_ << '\n';
    
        return true;
      }
    
      const std::string& getName() const
      {
        return name_;
      }
    };
    
    int            main()
    {
      auto lucy = std::make_shared<Person>("Lucy");
      auto ricky = std::make_shared<Person>("Ricky");
    
      partnerUp(lucy, ricky);
    }
    
    /* stdout stderr
    Lucy created
    Ricky created
    Lucy is partnered with Ricky
    Ricky destroyed
    Lucy destroyed
    */
  • mutex처럼 lock이 걸린 상태에서만 개수를 세기 때문에, 인스턴스를 사용 중이 아니면 소멸자를 호출할 수 있는 원리이다.

    • lock 함수를 사용하면 shared_ptr를 반환한다.

      #include <iostream>
      #include <memory>
      
      class Person
      {
        std::string                name_;
        std::weak_ptr<Person>    partner_;
      
      public:
        Person(const std::string& name) : name_(name)
        {
          std::cout << name_ << " created\n";
        }
      
        ~Person()
        {
          std::cout << name_ << " destroyed\n";
        }
      
        friend bool partnerUp(std::shared_ptr<Person>& p1, std::shared_ptr<Person>& p2)
        {
          if (!p1 || !p2)
            return false;
      
          p1->partner_ = p2;
          p2->partner_ = p1;
      
          std::cout << p1->name_ << " is partnered with " << p2->name_ << '\n';
      
          return true;
        }
      
        const std::string& getName() const
        {
          return name_;
        }
      
        const std::shared_ptr<Person> getPartner() const
        {
          return partner_.lock();
        }
      };
      
      int            main()
      {
        auto lucy = std::make_shared<Person>("Lucy");
        auto ricky = std::make_shared<Person>("Ricky");
      
        partnerUp(lucy, ricky);
      
        std::cout << lucy->getName() << std::endl;
        std::cout << lucy->getPartner()->getName() << std::endl;
      }
      
      /* stdout stderr
      Lucy created
      Ricky created
      Lucy is partnered with Ricky
      Lucy
      Ricky
      Ricky destroyed
      Lucy destroyed
      */

'C++ > Library' 카테고리의 다른 글

C++ STL 컨테이너 (STL Containers)  (0) 2021.03.24
C++ 표준 템플릿 라이브러리 (STL, Standard Template Libraries)  (0) 2021.03.24
C++ shared_ptr  (0) 2021.03.24
C++ unique_ptr  (0) 2021.03.24
C++ std::move  (0) 2021.03.24
C++/Library 2021. 3. 24. 10:47

shared_ptr

shared_ptr

  • <memory> 라이브러리

  • 몇 개의 변수가 포인터를 참조하고 있는지 내부적으로 계산한다.


예제

main.cpp

  #include <iostream>
  #include <memory>
  #include "Resource.h"

  int            main()
  {
    Resource* res = new Resource(3);
    res->setAll(1);

    {
      std::shared_ptr<Resource> ptr1(res);

      ptr1->print();

      {
        std::shared_ptr<Resource> ptr2(ptr1);

        ptr2->setAll(3);
        ptr2->print();

        std::cout << "Going out of the block\n";
      }

      ptr1->print();
      std::cout << "Going out of the outer block\n";
    }
    std::cout << "Last of main function\n";
  }

  /* stdout stderr
  Resource length constructed
  1 1 1
  3 3 3
  Going out of the block
  3 3 3
  Going out of the outer block
  Resource destoryed
  Last of main function
  */

Resource.h

  #pragma once

  #include <iostream>

  class Resource
  {
  public:
    int    *data_ = nullptr;
    unsigned length_ = 0;

    Resource()
    {
      std::cout << "Resource default constructed\n";
    }

    Resource(unsigned length)
    {
      std::cout << "Resource length constructed\n";
      init(length);
    }

    Resource(const Resource& res)
    {
      std::cout << "Resource copy constructed\n";
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
    }

    ~Resource()
    {
      std::cout << "Resource destoryed\n";

      if (data_ != nullptr) delete[] data_;
    }

    void    init(unsigned length)
    {
      data_ = new int[length];
      length_ = length;
    }

    Resource& operator = (Resource& res)
    {
      std::cout << "Resource copy assignment\n";
      if (&res == this) return *this;

      if (data_ != nullptr) delete[] data_;
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
      return *this;
    }

    void    print()
    {
      for (unsigned i = 0; i < length_; ++i)
        std::cout << data_[i] << ' ';
      std::cout << std::endl;
    }

    void    setAll(const int& v)
    {
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = v;
    }
  };
  • 아래와 같이 ptr2를 생성하면 ptr1에서 알 수 없기 때문에 에러가 발생한다.

    std::shared_ptr<Resource> ptr2(res);
  • make_shared를 사용해서 직접 초기화하는 방법이 일반적이다.

    main.cpp

    #include <iostream>
    #include <memory>
    #include "Resource.h"
    
    int            main()
    {
      {
        auto ptr1 = std::make_shared<Resource>(3);
        ptr1->setAll(1);
        ptr1->print();
    
        {
          auto ptr2 = ptr1;
    
          ptr2->setAll(3);
          ptr2->print();
    
          std::cout << "Going out of the block\n";
        }
    
        ptr1->print();
        std::cout << "Going out of the outer block\n";
      }
      std::cout << "Last of main function\n";
    }
    
    /* stdout stderr
    Resource length constructed
    1 1 1
    3 3 3
    Going out of the block
    3 3 3
    Going out of the outer block
    Resource destoryed
    Last of main function
    */

'C++ > Library' 카테고리의 다른 글

C++ 표준 템플릿 라이브러리 (STL, Standard Template Libraries)  (0) 2021.03.24
C++ weak_ptr  (0) 2021.03.24
C++ unique_ptr  (0) 2021.03.24
C++ std::move  (0) 2021.03.24
C++ 출력 스트림 끊기  (0) 2021.03.24
C++/Library 2021. 3. 24. 10:47

unique_ptr

unique_ptr

  • <memory> 라이브러리

  • scope를 벗어나면 자동으로 메모리를 해제하므로 메모리 누수를 방지할 수 있다.


예제

main.cpp

  #include <iostream>
  #include <memory>
  #include "Resource.h"

  using namespace std;

  int            main()
  {
    std::unique_ptr<Resource> res(new Resource(100000000));
  }
  /* stdout
  Resource length constructed
  Resource destoryed
  */

Resource.h

  #pragma once

  #include <iostream>

  class Resource
  {
  public:
    int    *data_ = nullptr;
    unsigned length_ = 0;

    Resource()
    {
      std::cout << "Resource default constructed\n";
    }

    Resource(unsigned length)
    {
      std::cout << "Resource length constructed\n";
      init(length);
    }

    Resource(const Resource& res)
    {
      std::cout << "Resource copy constructed\n";
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
    }

    ~Resource()
    {
      std::cout << "Resource destoryed\n";

      if (data_ != nullptr) delete[] data_;
    }

    void    init(unsigned length)
    {
      data_ = new int[length];
      length_ = length;
    }

    Resource& operator = (Resource& res)
    {
      std::cout << "Resource copy assignment\n";
      if (&res == this) return *this;

      if (data_ != nullptr) delete[] data_;
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
      return *this;
    }

    void    print()
    {
      for (unsigned i = 0; i < length_; ++i)
        std::cout << data_[i] << ' ';
      std::cout << std::endl;
    }

    void    setAll(const int& v)
    {
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = v;
    }
  };

make_unique

  • unique_ptr를 안전하게 반환하는 함수

    main.cpp

    #include <iostream>
    #include <memory>
    #include "Resource.h"
    
    using namespace std;
    
    auto        doSomething()
    {
      //return std::unique_ptr<Resource>(new Resource(5));
      return std::make_unique<Resource>(5); // 이걸 더 추천
    }
    
    int            main()
    {
      auto res1 = doSomething();
    
      res1->setAll(5);
    
      std::unique_ptr<Resource> res2;
    
      if (res1 != nullptr)
      {
        cout << "res1 : ";
        res1->print();
      }
      if (res2 != nullptr)
      {
        cout << "res2 : ";
        res2->print();
      }
    
      cout << boolalpha;
      cout << "res1 : " << static_cast<bool>(res1) << endl;
      cout << "res2 : " << static_cast<bool>(res2) << endl;
      cout << '\n';
    
      res2 = std::move(res1);
    
      if (res1 != nullptr) 
      {
        cout << "res1 : ";
        res1->print();
      }
      if (res2 != nullptr) 
      {
        cout << "res2 : ";
        res2->print();
      }
    
      cout << "res1 : " << static_cast<bool>(res1) << endl;
      cout << "res2 : " << static_cast<bool>(res2) << endl;
    }
    
    /* stdout stderr
    Resource length constructed
    res1 : 5 5 5 5 5
    res1 : true
    res2 : false
    
    res2 : 5 5 5 5 5
    res1 : false
    res2 : true
    Resource destoryed
    */
    • 아래의 명령은 에러가 발생한다.

      main.cpp

      res2 = res1;
      error C2280: 'std::unique_ptr<Resource,std::default_delete<Resource>> &std::unique_ptr<Resource,std::default_delete<Resource>>::operator =(const std::unique_ptr<Resource,std::default_delete<Resource>> &)': attempting to reference a deleted function
      • unique_ptr는 말 그대로 포인터를 단독 사용하기 위해 쓰는 클래스이므로, 라이브러리 자체에서 복사 대입(copy assignment, operator =)을 delete한 것이다.

copy constructordelete한 상태임을 보여주는 예제

main.cpp

  #include <iostream>
  #include <memory>
  #include "Resource.h"

  using namespace std;

  auto        doSomething(std::unique_ptr<Resource> res)  // 에러
  {
    res->setAll(10);
  }

  int            main()
  {
    auto res1 = std::make_unique<Resource>(5);
    res1->setAll(1);
    res1->print();

    doSomething(res1);

    res1->print();
  }
  error C2280: 'std::unique_ptr<Resource,std::default_delete<Resource>>::unique_ptr(const std::unique_ptr<Resource,std::default_delete<Resource>> &)': attempting to reference a deleted function
  • 에러 메시지를 통해 라이브러리에서 복사 생성자(copy constructor)를 delete한 것임을 알 수 있다.
  • 이 예제에서 doSomething(std::move(res1)) 과 같이 R-value로 넘기면, doSomething 함수 내부로 unique_ptrres1이 옮겨간다.

    • 해당 함수의 scope 밖으로 나오는 순간(함수가 끝나고 스택이 되감길 때) unique_ptr의 특성으로 res가 사라진다.

    • 글로 설명하는 것보다 예제를 보는게 쉽다.

    main.cpp

    #include <iostream>
    #include <memory>
    #include "Resource.h"
    
    using namespace std;
    
    auto        doSomething(std::unique_ptr<Resource> res)
    {
      res->setAll(10);
    }
    
    int            main()
    {
      auto res1 = std::make_unique<Resource>(5);
      res1->setAll(1);
      res1->print();
    
      cout << boolalpha << static_cast<bool>(res1) << endl;
    
      doSomething(std::move(res1));
    
      cout << static_cast<bool>(res1) << endl;
    }
    
    /* stdout stderr
    Resource length constructed
    1 1 1 1 1
    true
    Resource destoryed
    false
    */

get()

  • unique_ptr로 가지고 있는 포인터를 반환한다.

<memory>

// STRUCT TEMPLATE _Get_deleter_pointer_type
template <class _Ty, class _Dx_noref, class = void>
struct _Get_deleter_pointer_type { // provide fallback
    using type = _Ty*;
};

...

template <class _Ty, class _Dx /* = default_delete<_Ty> */>
class unique_ptr {
public:
  using pointer      = typename _Get_deleter_pointer_type<_Ty, remove_reference_t<_Dx>>::type;

...

_NODISCARD pointer get() const noexcept {
    return _Mypair._Myval2;
}

...

private:
  template <class, class>
  friend class unique_ptr;

  _Compressed_pair<_Dx, pointer> _Mypair;
};

<xmemory>

template <class _Ty1, class _Ty2, bool = is_empty_v<_Ty1> && !is_final_v<_Ty1>>
class _Compressed_pair final : private _Ty1 { // store a pair of values, deriving from empty first
public:
    _Ty2 _Myval2;

...
};

'C++ > Library' 카테고리의 다른 글

C++ weak_ptr  (0) 2021.03.24
C++ shared_ptr  (0) 2021.03.24
C++ std::move  (0) 2021.03.24
C++ 출력 스트림 끊기  (0) 2021.03.24
C++ std::exception  (0) 2021.03.22
C++/Library 2021. 3. 24. 10:45

std::move

  • <utility> 라이브러리

  • 인자로 들어온 값을 R-value로 리턴해준다.


예제

  • std::move를 사용하지 않은 예제

    main.cpp

    #include <iostream>
    #include "Resource.h"
    #include "AutoPtr.h"
    using namespace std;
    
    int            main()
    {
      AutoPtr<Resource> res1(new Resource(10000000));
    
      cout << res1.ptr_ << endl;
    
      AutoPtr<Resource> res2 = res1;
    
      cout << res1.ptr_ << endl;
      cout << res2.ptr_ << endl;
    }
    
    /* stdout stderr
    Resource length constructed
    AutoPtr default constructor
    0158E360
    AutoPtr copy constructor
    Resource default constructed
    Resource copy assignment
    0158E360
    0158E408
    AutoPtr destructor
    Resource destoryed
    AutoPtr destructor
    Resource destoryed
    */

    Resource.h

    #pragma once
    
    #include <iostream>
    
    class Resource
    {
    public:
      int    *data_ = nullptr;
      unsigned length_ = 0;
    
      Resource()
      {
        std::cout << "Resource default constructed\n";
      }
    
      Resource(unsigned length)
      {
        std::cout << "Resource length constructed\n";
        init(length);
      }
    
      Resource(const Resource& res)
      {
        std::cout << "Resource copy constructed\n";
        init(res.length_);
        for (unsigned i = 0; i < length_; ++i)
          data_[i] = res.data_[i];
      }
    
      ~Resource()
      {
        std::cout << "Resource destoryed\n";
    
        if (data_ != nullptr) delete[] data_;
      }
    
      void    init(unsigned length)
      {
        data_ = new int[length];
        length_ = length;
      }
    
      Resource& operator = (Resource& res)
      {
        std::cout << "Resource copy assignment\n";
        if (&res == this) return *this;
    
        if (data_ != nullptr) delete[] data_;
        init(res.length_);
        for (unsigned i = 0; i < length_; ++i)
          data_[i] = res.data_[i];
        return *this;
      }
    
      void print()
      {
        for (unsigned i = 0; i < length_; ++i)
          std::cout << data_[i] << ' ';
        std::cout << std::endl;
      }
    };

    AutoPtr.h

    #pragma once
    
    #include <iostream>
    
    template<class T>
    class AutoPtr
    {
    public:
      T* ptr_;
    
      AutoPtr(T *ptr = nullptr)
        : ptr_(ptr)
      {
        std::cout << "AutoPtr default constructor\n";
      }
    
      AutoPtr(const AutoPtr& a)
        : ptr_(a.ptr_)
      {
        std::cout << "AutoPtr copy constructor\n";
        ptr_ = new T;
        *ptr_ = *a.ptr_;
      }
    
      AutoPtr(AutoPtr&& a)
        : ptr_(a.ptr_)
      {
        std::cout << "AutoPtr move constructor\n";
        a.ptr_ = nullptr;
      }
    
      ~AutoPtr()
      {
        std::cout << "AutoPtr destructor\n";
        if (ptr_ != nullptr) delete ptr_;
      }
    
      AutoPtr& operator = (const AutoPtr& a)
      {
        std::cout << "AutoPtr copy assignment\n";
        if (&a == this)
          return *this;
    
        if (ptr_ != nullptr) delete ptr_;
    
        ptr_ = new T;
        *ptr_ = *a.ptr_;
        return *this; 
      }
    
      AutoPtr& operator = (AutoPtr&& a)
      {
        std::cout << "AutoPtr move assignment\n";
    
        if (&a == this)
          return *this;
    
        if (ptr_ != nullptr) delete ptr_;
    
        ptr_ = a.ptr_;
        a.ptr_ = nullptr;
    
        return *this;
      }
    };

  • 위의 코드에서 main.cpp<utility> 라이브러리를 include 하고, std::move를 사용하면 다음과 같다.

    main.cpp

    #include <iostream>
    #include <utility>
    #include "Resource.h"
    #include "AutoPtr.h"
    using namespace std;
    
    int            main()
    {
      AutoPtr<Resource> res1(new Resource(10000000));
    
      cout << res1.ptr_ << endl;
    
      AutoPtr<Resource> res2 = std::move(res1);
    
      cout << res1.ptr_ << endl;
      cout << res2.ptr_ << endl;
    }
    
    /* stdout stderr
    Resource length constructed
    AutoPtr default constructor
    00CADF50
    AutoPtr move constructor
    00000000
    00CADF50
    AutoPtr destructor
    Resource destoryed
    AutoPtr destructor
    */

Swap 예제

main.cpp

  #include <iostream>
  #include <utility>
  #include "Resource.h"
  #include "AutoPtr.h"
  using namespace std;

  template<typename T>
  void        MySwap(T& a, T& b)
  {
    T tmp{ std::move(a) };
    a = std::move(b);
    b = std::move(tmp);
  }

  int            main()
  {
    AutoPtr<Resource> res1(new Resource(3));
    res1->setAll(3);

    AutoPtr<Resource> res2(new Resource(5));
    res2->setAll(5);

    res1->print();
    res2->print();

    MySwap(res1, res2);

    res1->print();
    res2->print();
  }

  /* stdout stderr
  Resource length constructed
  AutoPtr default constructor
  Resource length constructed
  AutoPtr default constructor
  3 3 3
  5 5 5 5 5
  AutoPtr move constructor
  AutoPtr move assignment
  AutoPtr move assignment
  AutoPtr destructor
  5 5 5 5 5
  3 3 3
  AutoPtr destructor
  Resource destoryed
  AutoPtr destructor
  Resource destoryed
  */

Resource.h

  #pragma once

  #include <iostream>

  class Resource
  {
  public:
    int    *data_ = nullptr;
    unsigned length_ = 0;

    Resource()
    {
      std::cout << "Resource default constructed\n";
    }

    Resource(unsigned length)
    {
      std::cout << "Resource length constructed\n";
      init(length);
    }

    Resource(const Resource& res)
    {
      std::cout << "Resource copy constructed\n";
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
    }

    ~Resource()
    {
      std::cout << "Resource destoryed\n";

      if (data_ != nullptr) delete[] data_;
    }

    void    init(unsigned length)
    {
      data_ = new int[length];
      length_ = length;
    }

    Resource& operator = (Resource& res)
    {
      std::cout << "Resource copy assignment\n";
      if (&res == this) return *this;

      if (data_ != nullptr) delete[] data_;
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
      return *this;
    }

    void    print()
    {
      for (unsigned i = 0; i < length_; ++i)
        std::cout << data_[i] << ' ';
      std::cout << std::endl;
    }

    void    setAll(const int& v)
    {
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = v;
    }
  };

AutoPtr.h

  #pragma once

  #include <iostream>

  template<class T>
  class AutoPtr
  {
  public:
    T* ptr_;

    AutoPtr(T *ptr = nullptr)
      : ptr_(ptr)
    {
      std::cout << "AutoPtr default constructor\n";
    }

    AutoPtr(const AutoPtr& a)
      : ptr_(a.ptr_)
    {
      std::cout << "AutoPtr copy constructor\n";
      ptr_ = new T;
      *ptr_ = *a.ptr_;
    }

    AutoPtr(AutoPtr&& a)
      : ptr_(a.ptr_)
    {
      std::cout << "AutoPtr move constructor\n";
      a.ptr_ = nullptr;
    }

    ~AutoPtr()
    {
      std::cout << "AutoPtr destructor\n";
      if (ptr_ != nullptr) delete ptr_;
    }

    AutoPtr& operator = (const AutoPtr& a)
    {
      std::cout << "AutoPtr copy assignment\n";
      if (&a == this)
        return *this;

      if (ptr_ != nullptr) delete ptr_;

      ptr_ = new T;
      *ptr_ = *a.ptr_;
      return *this; 
    }

    AutoPtr& operator = (AutoPtr&& a)
    {
      std::cout << "AutoPtr move assignment\n";

      if (&a == this)
        return *this;

      if (ptr_ != nullptr) delete ptr_;

      ptr_ = a.ptr_;
      a.ptr_ = nullptr;

      return *this;
    }

      T* operator->() const { return ptr_; }
  };

대부분의 라이브러리는 R-value에 대해서도 정의가 되어있다.

  #include <iostream>
  #include <utility>
  #include <vector>
  using namespace std;

  int            main()
  {
    vector<string> v;
    string str = "Hello";

    v.push_back(str);

    cout << str << endl;
    cout << v[0] << endl;

    v.push_back(std::move(str));

    cout << str << endl;
    cout << v[0] << ' ' << v[1] << endl;
  }

  /* stdout stderr
  Hello
  Hello

  Hello Hello
  */

'C++ > Library' 카테고리의 다른 글

C++ shared_ptr  (0) 2021.03.24
C++ unique_ptr  (0) 2021.03.24
C++ 출력 스트림 끊기  (0) 2021.03.24
C++ std::exception  (0) 2021.03.22
C++ reference_wrapper  (0) 2021.03.21
C++/Library 2021. 3. 24. 10:43

출력 스트림 끊기

  • <iostream> 라이브러리 사용

  • std::cout.rdbuf(streambuf *)

    <iosfwd>

    using streambuf     = basic_streambuf<char, char_traits<char>>;

    <ios>

    using _Mysb       = basic_streambuf<_Elem, _Traits>;
    
    ...
    
    _Mysb* __CLR_OR_THIS_CALL rdbuf(_Mysb* _Strbuf) { // set stream buffer pointer
        _Mysb* _Oldstrbuf = _Mystrbuf;
        _Mystrbuf         = _Strbuf;
        clear();
        return _Oldstrbuf;
    }
    • 인자로 입력한 stream buffer pointer를 출력 스트림으로 지정한다.

    • 예제

      #include <iostream>
      
      using namespace std;
      
      int            main()
      {
        streambuf* orig_buf = cout.rdbuf();
        cout.rdbuf(NULL);
      
        cout << "Hello ";
      
        cout.rdbuf(orig_buf);
      
        cout << "World\n";
      }
      
      /* stdout
      World
      */

'C++ > Library' 카테고리의 다른 글

C++ unique_ptr  (0) 2021.03.24
C++ std::move  (0) 2021.03.24
C++ std::exception  (0) 2021.03.22
C++ reference_wrapper  (0) 2021.03.21
C++ IntArray  (0) 2021.03.19
C++/Library 2021. 3. 22. 00:11

std::exception

  • <exception> 라이브러리

exception 클래스

  • 자식으로 여러 클래스를 가지고 있다.

  • std::exception::what() 함수를 통해 예외 상황을 알 수 있다.

    • 다음과 같이 exception 클래스에서는 가상함수로 정의되어있다.

      _NODISCARD virtual char const* what() const
      {
          return _Data._What ? _Data._What : "Unknown exception";
      }
    • https://en.cppreference.com/w/cpp/error/length_error 에 상속 다이어그램이 있으니 참고하면 좋다.

    #include <iostream>
    #include <exception>
    
    using namespace std;
    
    int            main()
    {
      try
      {
        string    s;
        s.resize(-1);
      }
      catch (std::exception & exception)
      {
        cout << typeid(exception).name() << endl;
        cerr << exception.what() << endl;
      }
    }
    
    /* stdout stderr
    class std::length_error
    string too long
    */
  • 직접 자식 클래스를 던질 수도 있다.

    #include <iostream>
    #include <exception>
    
    using namespace std;
    
    int            main()
    {
      try
      {
        throw std::runtime_error("Bad thing happened");
      }
      catch (std::exception & exception)
      {
        cout << typeid(exception).name() << endl;
        cerr << exception.what() << endl;
      }
    }
    
    /* stdout stderr
    class std::runtime_error
    Bad thing happened
    */

직접 상속받는 클래스 만들기

  • std::exception 클래스를 상속받아 새로운 클래스를 정의하고 이를 사용할 수 있다.

    • what 함수를 오버라이딩해야 의미가 있다.

    • noexcept

      • C++11

      • 예외를 던지지 않는다는 뜻이다. 없어도 되는 것 같다.

    #include <iostream>
    #include <exception>
    
    using namespace std;
    
    class CustomException : public std::exception
    {
    public:
      const char* what() const noexcept override
      {
        return "Custom exception";
      }
    };
    
    int            main()
    {
      try
      {
        throw CustomException();
      }
      catch (std::exception & exception)
      {
        cout << typeid(exception).name() << endl;
        cerr << exception.what() << endl;
      }
    }
    
    /* stdout stderr
    class CustomException
    Custom exception
    */

'C++ > Library' 카테고리의 다른 글

C++ std::move  (0) 2021.03.24
C++ 출력 스트림 끊기  (0) 2021.03.24
C++ reference_wrapper  (0) 2021.03.21
C++ IntArray  (0) 2021.03.19
C++ initializer_list  (0) 2021.03.19
C++/Library 2021. 3. 21. 23:53

reference_wrapper

  • <functional> 라이브러리

  • 템플릿 등에 레퍼런스로 전달할 수 있게 해주는 클래스이다.


예제

  #include <iostream>
  #include <vector>
  #include <functional>

  class Base
  {
  public:
    int    i_ = 0;

    virtual void print()
    {
      std::cout << "I'm Base\n";
    }
  };

  class Derived : public Base
  {
  public:
    int    j_ = 1;

    virtual void print() override
    {
      std::cout << "I'm Derived\n";
    }
  };

  void        doSomething(Base& b)
  {
    b.print();
  }

  int            main()
  {
    using namespace std;

    Base    b;
    Derived    d;

    vector<std::reference_wrapper<Base>> my_vec;
    my_vec.push_back(b);
    my_vec.push_back(d);

    for (auto& e : my_vec)
      e.get().print();
  }

  /* stdout
  I'm Base
  I'm Derived
  */

'C++ > Library' 카테고리의 다른 글

C++ 출력 스트림 끊기  (0) 2021.03.24
C++ std::exception  (0) 2021.03.22
C++ IntArray  (0) 2021.03.19
C++ initializer_list  (0) 2021.03.19
C++ chrono  (0) 2021.03.16
C++/Library 2021. 3. 19. 19:42

IntArray

  • int 자료형을 여러개 담을 수 있는 컨테이너

    #include <iostream>
    
    class IntArray
    {
        int*        data_ = nullptr;
        unsigned    length_ = 0;
    
    public:
        IntArray(unsigned length = 0)
        {
            initialize(length);
        }
    
        IntArray(const std::initializer_list<int>& list)
        {
            initialize(list.size());
            int count = 0;
            for (auto& e : list)
                data_[count++] = e;
        }
    
        ~IntArray()
        {
            delete[] data_;
        }
    
        void    initialize(unsigned length)
        {
            length_ = length;
            if (length_ > 0)
                data_ = new int[length_];
        }
    
        void    reset()
        {
            if (data_)
            {
                delete[] data_;
                data_ = nullptr;
            }
            length_ = 0;
        }
    
        void    resize(const unsigned& length)
        {
            if (length == 0)
                reset();
            else if (length_ < length)
            {
                int* new_data_ = new int[length];
                for (unsigned i = 0; i < length_; ++i)
                    new_data_[i] = data_[i];
                delete[] data_;
                data_ = new_data_;
            }
            length_ = length;
        }
    
        void    insertBefore(const int& value, const int& ix)
        {
            resize(length_ + 1);
            for (int i = length_ - 2; i >= ix; --i)
                data_[i + 1] = data_[i];
            data_[ix] = value;
        }
    
        void    remove(const int& ix)
        {
            for (int i = ix; i < length_ - 1; ++i)
                data_[i] = data_[i + 1];
            --length_;
            if (length_ <= 0)
                reset();
        }
    
        void    push_back(const int& value)
        {
            insertBefore(value, length_);
        }
    
        friend std::ostream& operator << (std::ostream& out, const IntArray& arr)
        {
            for (unsigned i = 0; i < arr.length_; ++i)
                out << arr.data_[i] << ' ';
            return out;
        }
    };
    
    int        main()
    {
        using namespace std;
    
        IntArray my_arr{ 1, 3, 5, 7, 9 };
        cout << my_arr << endl;
    
        my_arr.insertBefore(10, 1);
        cout << my_arr << endl;
    
        my_arr.remove(3);
        cout << my_arr << endl;
    
        my_arr.push_back(13);
        cout << my_arr << endl;
    }
    
    /* stdout
    1 3 5 7 9
    1 10 3 5 7 9
    1 10 3 7 9
    1 10 3 7 9 13
    */

'C++ > Library' 카테고리의 다른 글

C++ std::exception  (0) 2021.03.22
C++ reference_wrapper  (0) 2021.03.21
C++ initializer_list  (0) 2021.03.19
C++ chrono  (0) 2021.03.16
C++ assert  (0) 2021.03.12
C++/Library 2021. 3. 19. 19:35

initializer_list

  • C++11

  • <initializer_list> 라이브러리

  • [] 연산자를 사용할 수 없다.

    • foreach문은 내부적으로 iterator를 사용한다.

    • 내부적으로 iterator를 사용하는 foreach문으로 반복문을 구성하면 된다.

      #include <iostream>
      //#include <initializer_list>
      
      class IntArray
      {
          unsigned    len_ = 0;
          int*        data_ = nullptr;
      
      public:
          IntArray(unsigned length)
              : len_(length)
          {
              data_ = new int[len_];
          }
      
          IntArray(const std::initializer_list<int>& list)
              : IntArray(list.size())
          {
              int count = 0;
              for (auto& e : list)
              {
                  data_[count] = e;
                  ++count;
              }
          }
      
          ~IntArray()
          {
              delete[] data_;
          }
      
          friend std::ostream& operator << (std::ostream& out, const IntArray& arr)
          {
              for (unsigned i = 0; i < arr.len_; ++i)
              {
                  out << arr.data_[i] << ' ';
              }
              return out;
          }
      };
      
      int        main()
      {
          using namespace std;
      
          auto il = { 10, 20 , 30 };  // std::initializer_list<int>
      
          IntArray arr1{ il };
          cout << arr1 << endl;
      
          IntArray arr2 = { 1, 2, 3, 4, 5 };
          cout << arr2 << endl;
      }
      
      /* stdout
      10 20 30
      1 2 3 4 5
      */

'C++ > Library' 카테고리의 다른 글

C++ reference_wrapper  (0) 2021.03.21
C++ IntArray  (0) 2021.03.19
C++ chrono  (0) 2021.03.16
C++ assert  (0) 2021.03.12
C++ vector  (0) 2021.03.12
C++/Library 2021. 3. 16. 00:13

chrono

  • <chrono> 라이브러리

    • C++11

    • 실행 시간 측정(Run Time Measurement)에 사용되며, 시간을 비교적 정밀하게 측정할 수 있다.

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <random>
    #include <chrono>
    
    using namespace std;
    
    class Timer
    {
      using clock_t = std::chrono::high_resolution_clock;
      using second_t = std::chrono::duration<double, std::ratio<1>>;
    
      std::chrono::time_point<clock_t> start_time = clock_t::now();
    
    public:
      void elapsed()
      {
        std::chrono::time_point<clock_t> end_time = clock_t::now();
    
        std::cout << std::chrono::duration_cast<second_t>(end_time - start_time).count() << std::endl;
      }
    };
    
    int        main()
    {
      random_device    rnd_device;
      mt19937            mersenne_engin{ rnd_device() };
    
      vector<int>        vec(100000);
      for (size_t i = 0; i < vec.size(); ++i)
        vec[i] = i;
    
      std::shuffle(begin(vec), end(vec), mersenne_engin);
    
      /*for (auto& e : vec) cout << e << ' ';
      cout << endl;*/
    
      Timer timer;
    
      std::sort(begin(vec), end(vec));
    
      timer.elapsed();
    
      /*for (auto& e : vec) cout << e << ' ';
      cout << endl;*/
    }

'C++ > Library' 카테고리의 다른 글

C++ IntArray  (0) 2021.03.19
C++ initializer_list  (0) 2021.03.19
C++ assert  (0) 2021.03.12
C++ vector  (0) 2021.03.12
C++ tuple  (0) 2021.03.12
C++/Library 2021. 3. 12. 17:33

assert

  • <cassert> 라이브러리

assert

  • Debug 모드에서만 런타임에 작동한다.

    • VS의 전처리기 설정에 매크로가 설정되어있다.

      • Debug 모드에서는 _DEBUG

      • Release 모드에서는 NDEBUG

  • 내부 조건이 거짓이면 Debug Error를 발생시킨다.

      #include <cassert>
    
      int     main()
      {
        assert(false);
      }
  • 최대한 나눠서 쓰는게 디버깅하기에 좋다.

  • static assert

  • 컴파일 타임에 작동한다.

  • Release 모드에서도 작동한다.

  • 에러 문구를 넣어야 한다.

      #include <cassert>
    
      int     main()
    {
        const int x = 5;
        //const int x = 4;  // 컴파일 안됨
    
        static_assert(x == 5, "x should be 5");
      }
  • 릴리즈 모드에선 작동되지 않는다면, 차라리 예외처리를 전부 하는게 맞는 것 아닌가 생각했다.

  • 관련 참고 내용

'C++ > Library' 카테고리의 다른 글

C++ initializer_list  (0) 2021.03.19
C++ chrono  (0) 2021.03.16
C++ vector  (0) 2021.03.12
C++ tuple  (0) 2021.03.12
C++ array  (0) 2021.03.11
C++/Library 2021. 3. 12. 17:31

vector

  • <vector> 라이브러리

기본 예제

  • push_back 함수로 벡터의 맨 뒤에 원소를 추가할 수 있다.

  • foreach로 반복문을 작성할 수 있다. (iterator가 존재하기 때문에 사용 가능)

    #include <iostream>
    #include <vector>
    
    int            main()
    {
      using namespace std;
    
      vector<int> vec;
      for (int i = 0; i < 10; ++i)
        vec.push_back(i);
      for (auto& e : vec)
        cout << e << ' ';
      cout << endl;
    }
    
    /* stdout stderr
    0 1 2 3 4 5 6 7 8 9
    */

멤버 함수

size()capacity()

  • size는 실제 사용하고 있는 공간이고, capacity는 할당받은 전체 공간이다.

    #include <iostream>
    #include <vector>
    
    int     main()
    {
        using namespace std;
    
        vector<int> v{ 1,2 ,3 };
    
        v.resize(2);
    
        for (auto& e : v)
            cout << e << ' ';
        cout << endl;
    
        cout << v.size() << ' ' << v.capacity() << endl;
    
        int* pv = &v[0];
        cout << pv[2] << endl;
    }
    
    /* stdout stderr
    1 2
    2 3
    3
    */

reserve()

  • 공간을 미리 할당받는 것

    #include <iostream>
    #include <vector>
    
    int     main()
    {
      using namespace std;
    
      vector<int> v{ 1,2 ,3 };
    
      v.reserve(100);
    
      for (auto& e : v)
        cout << e << ' ';
      cout << endl;
    
      cout << v.size() << ' ' << v.capacity() << endl;
    }
    
    /* stdout stderr
    1 2 3
    3 100
    */

참고

'C++ > Library' 카테고리의 다른 글

C++ chrono  (0) 2021.03.16
C++ assert  (0) 2021.03.12
C++ tuple  (0) 2021.03.12
C++ array  (0) 2021.03.11
C++ typeinfo  (0) 2021.03.11
C++/Library 2021. 3. 12. 17:25

tuple

  • C++11

  • <tuple> 라이브러리

    #include <iostream>
    #include <tuple>
    
    std::tuple<int, double> getTuple()
    {
      return (std::make_tuple(10, 3.14));
    }
    
    int     main()
    {
      using namespace std;
    
      tuple<int, double>    my_tp = getTuple();
      cout << get<0>(my_tp) << endl;
      cout << get<1>(my_tp) << endl;
    }
    
    /* stdout stderr
    10
    3.14
    */
  • C++17

    • 다음과 같이 작성 가능

      #include <iostream>
      #include <tuple>
      
      std::tuple<int, double> getTuple()
      {
        return (std::make_tuple(10, 3.14));
      }
      
      int     main()
      {
        using namespace std;
      
        auto [a, d] = getTuple();
        cout << a << endl;  // 10
        cout << d << endl;  // 3.14
      }
      
      /* stdout stderr
      10
      3.14
      */

'C++ > Library' 카테고리의 다른 글

C++ assert  (0) 2021.03.12
C++ vector  (0) 2021.03.12
C++ array  (0) 2021.03.11
C++ typeinfo  (0) 2021.03.11
C++ cin.ignore  (0) 2021.03.11
C++/Library 2021. 3. 11. 16:49

<array>

std::array<T, N>

  • C++11

  • size(), begin(), end(), at() 등의 함수 사용 가능

    • at()으로 접근하는 것은 arr[1] 처럼 직접 주소로 접근하는 것보다 느리지만 조금 더 안전하다.

      • at() 함수는 std::exception을 통해 예외 처리가 되어있다.
  • algorithm 라이브러리의 sort 함수 사용 가능

'C++ > Library' 카테고리의 다른 글

C++ vector  (0) 2021.03.12
C++ tuple  (0) 2021.03.12
C++ typeinfo  (0) 2021.03.11
C++ cin.ignore  (0) 2021.03.11
C++ cin  (0) 2021.03.11
C++/Library 2021. 3. 11. 16:49

데이터 타입 확인

  • <typeinfo> 라이브러리의 typeid().name()을 사용한다.

      cout << typeid(4.0).name() << endl;  // double

'C++ > Library' 카테고리의 다른 글

C++ tuple  (0) 2021.03.12
C++ array  (0) 2021.03.11
C++ cin.ignore  (0) 2021.03.11
C++ cin  (0) 2021.03.11
C++ 난수 생성 (Random Number Generation)  (0) 2021.03.11
C++/Library 2021. 3. 11. 16:35

입력 버퍼 무시하기

  • cin.ignore(_Count, _Metadelim)

  • _Count : 무시할 문자의 최대 개수(바이트)

    • 기본 값은 1

    • 정석대로라면 <limits> 라이브러리의 std::numeric_limits<std::streamsize>::max()를 사용하는게 맞으나... 귀찮으므로 보통 적당히 큰 수를 채택하는 것 같다.

  • _Metadelim : 이 문자가 나올 때까지 무시한다.(해당 문자 포함)

    • 기본 값은 eof
#include <iostream>

int     getInt()
{
  while (true)
  {
    int x;

    std::cout << "Enter an integer number : ";
    std::cin >> x;
    if (std::cin.fail())
    {
      std::cin.clear();
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
      std::cout << "Invalid number, please try again\n";
    }
    else
    {
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
      return (x);
    }
  }
}

char    getOperator()
{
  while (true)
  {
    char op;

    std::cout << "Enter an operator (+, -) : ";
    std::cin >> op;
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    if (op == '+' || op == '-')
      return (op);
    else
      std::cout << "Invalid Operator, please try again" << std::endl;
  }
}

void    printResult(int a, char op, int b)
{
  if (op == '+')      std::cout << a + b << std::endl;
  else if (op == '-') std::cout << a - b << std::endl;
  else                std::cout << "Invalid operator" << std::endl;
}

int     main()
{
  using namespace std;

  int     a = getInt();
  char    op = getOperator();
  int     b = getInt();

  printResult(a, op, b);
}

'C++ > Library' 카테고리의 다른 글

C++ array  (0) 2021.03.11
C++ typeinfo  (0) 2021.03.11
C++ cin  (0) 2021.03.11
C++ 난수 생성 (Random Number Generation)  (0) 2021.03.11
C++ 입력 버퍼 무시하기  (0) 2021.03.10
C++/Library 2021. 3. 11. 16:34

cin

현재 내가 사용하는 윈도우 컴퓨터 기준으로 작성했다.

상속 관계

  • cinistream 라이브러리 내부 basic_istream 클래스의 객체이다.

  • basic_istream 클래스는 ios 라이브러리 내부 basic_ios 클래스를 상속받는다.

  • basic_ios 클래스는 xiosbase 라이브러리 내부 ios_base 클래스를 상속받는다.

  • ios_base 클래스는 _Iosb 클래스를 상속받는다.

    #define _CRTIMP2_IMPORT __declspec(dllimport)
    #define _CRTDATA2_IMPORT _CRTIMP2_IMPORT
    
    class _CRTIMP2_PURE_IMPORT ios_base : public _Iosb<int>;
    class basic_ios : public ios_base;
    class basic_istream : virtual public basic_ios<_Elem, _Traits>;
    using istream       = basic_istream<char, char_traits<char>>;
    __PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT istream cin;

_Iosb

  • 기본적인 비트마스크들이 설정되어있다.

    <xiosbase>

    static constexpr _Iostate goodbit = static_cast<_Iostate>(0x0);
    static constexpr _Iostate eofbit  = static_cast<_Iostate>(0x1);
    static constexpr _Iostate failbit = static_cast<_Iostate>(0x2);
    static constexpr _Iostate badbit  = static_cast<_Iostate>(0x4);
    flag meaning
    goodbit 오류가 없다
    eofbit 스트림으로부터 추출 작업(extracting operation) 진행 중 EOF에 도달
    failbit 마지막 입력 작업이 자체 내부 오류 때문에 실패
    badbit 스트림 버퍼의 입출력 작업이 실패

ios_base

  • operator! 연산자 오버로딩, clear(), rdstate(), setstate(), good(), eof(), fail(), bad() 등의 함수가 내장되어있다.

  • ios::fail()

    • failbitbadbit가 설정되어있으면 true 반환

    • operator!fail()을 호출한다.

  • ios::clear()

    • 오류 상태 플래그를 새로운 값으로 설정

      • 기본 값은 goodbit : 오류 상태 플래그를 0으로 초기화 시킨다.
  • ios::rdstate()

    • 오류 상태 플래그(error state flag)를 반환한다.

      • 위의 비트들과 AND 연산으로 플래그를 확인할 수 있다.

      • AND 연산은 귀찮으므로 그냥 ios::eof(), ios::fail(), ios::bad(), ios::good() 함수를 사용하자.


basic_ios

  • basic_istream, basic_ostream 클래스의 base class

  • clear(), setstate() 함수의 기본 값 설정


basic_istream

  • 각 자료형에 대해 operator>> 연산자 오버로딩으로 변수에 값을 넣도록 하였다.

    • 처음에 _Err = ios_base::goodbit 로 설정한 뒤 결과에 따라 _Myios::setstate(_Err) 로 오류 상태 플래그를 설정
  • use_facet 관련은 locale을 알아야 할 것 같다. 참고

    template <class _Ty>
      basic_istream& _Common_extract_with_num_get(_Ty& _Val) { // formatted extract with num_get
      ios_base::iostate _Err = ios_base::goodbit;
      const sentry _Ok(*this);
    
      if (_Ok) { // state okay, use facet to extract
        _TRY_IO_BEGIN
          _STD use_facet<_Nget>(this->getloc()).get(*this, {}, *this, _Err, _Val);
        _CATCH_IO_END
      }
    
      _Myios::setstate(_Err);
      return *this;
    }
    
    basic_istream& __CLR_OR_THIS_CALL operator>>(unsigned int& _Val){ // extract an unsigned int
        return _Common_extract_with_num_get(_Val);
    }
    ...

입력 버퍼 무시하기

'C++ > Library' 카테고리의 다른 글

C++ typeinfo  (0) 2021.03.11
C++ cin.ignore  (0) 2021.03.11
C++ 난수 생성 (Random Number Generation)  (0) 2021.03.11
C++ 입력 버퍼 무시하기  (0) 2021.03.10
C++ typeinfo  (0) 2021.03.10
C++/Library 2021. 3. 11. 16:32

난수 생성 (Random Number Generation)

Linear congruential generator

  • 선형 합동 생성기

    • 널리 알려진 유사난수 생성기이다.
    unsigned int    PRNG()  // Pseudo Random Number Generator
    {
        static unsigned int seed = 5523;  // seed number
    
        seed = 8253729 * seed + 2396403;
        return (seed % 32768);
    }

std::rand

  • std::rand() 함수로 나올 수 있는 최댓값인 RAND_MAX를 이용하여 범위를 제한한다.

    • 고르게 분포되지는 않는다.
    #include <iostream>
    
    int getRandomNumber(int min, int max)
    {
        static const double fraction = 1.0 / (RAND_MAX + 1.0);
    
        return (min + static_cast<int>((max - min + 1) * \
                                        std::rand() * fraction));
    }
    
    int main()
    {
        using namespace std;
    
        for (int i = 0; i < 10; ++i)
            cout << getRandomNumber(5, 8) << '\n';
    }

<random>

  • C++11

  • 위의 경우들보다 더 정교하다.

  • Mersenne Twister

    • 난수 발생 속도가 빠르고 메모리를 적게 차지한다.

    • 난수 발생 주기(똑같은 숫자가 발생하는 주기)가 메르센 소수인 2^19937 - 1이라서 이름이 mt19937이다.

    • 참고 : 케이플러스

    #include <iostream>
    #include <random>
    
    int main()
    {
        using namespace std;
    
        random_device   rd;
        mt19937         mersenne(rd());
        uniform_int_distribution<> dice(1, 6);
    
        for (int i = 0; i < 10; ++i)
            cout << dice(mersenne) << endl;
    }

'C++ > Library' 카테고리의 다른 글

C++ cin.ignore  (0) 2021.03.11
C++ cin  (0) 2021.03.11
C++ 입력 버퍼 무시하기  (0) 2021.03.10
C++ typeinfo  (0) 2021.03.10
C++ 출력 버퍼 비우기  (0) 2021.03.10
C++/Library 2021. 3. 10. 21:11

입력 버퍼 무시하기

  • cin.ignore(_Count, _Metadelim)

  • _Count : 무시할 문자의 최대 개수(바이트)

    • 기본 값은 1

    • 정석대로라면 <limits> 라이브러리의 std::numeric_limits<std::streamsize>::max()를 사용하는게 맞으나... 귀찮으므로 보통 적당히 큰 수를 채택하는 것 같다.

  • _Metadelim : 이 문자가 나올 때까지 무시한다.(해당 문자 포함)

    • 기본 값은 eof
#include <iostream>

int     getInt()
{
  while (true)
  {
    int x;

    std::cout << "Enter an integer number : ";
    std::cin >> x;
    if (std::cin.fail())
    {
      std::cin.clear();
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
      std::cout << "Invalid number, please try again\n";
    }
    else
    {
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
      return (x);
    }
  }
}

char    getOperator()
{
  while (true)
  {
    char op;

    std::cout << "Enter an operator (+, -) : ";
    std::cin >> op;
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    if (op == '+' || op == '-')
      return (op);
    else
      std::cout << "Invalid Operator, please try again" << std::endl;
  }
}

void    printResult(int a, char op, int b)
{
  if (op == '+')      std::cout << a + b << std::endl;
  else if (op == '-') std::cout << a - b << std::endl;
  else                std::cout << "Invalid operator" << std::endl;
}

int     main()
{
  using namespace std;

  int     a = getInt();
  char    op = getOperator();
  int     b = getInt();

  printResult(a, op, b);
}

'C++ > Library' 카테고리의 다른 글

C++ cin.ignore  (0) 2021.03.11
C++ cin  (0) 2021.03.11
C++ 난수 생성 (Random Number Generation)  (0) 2021.03.11
C++ typeinfo  (0) 2021.03.10
C++ 출력 버퍼 비우기  (0) 2021.03.10
C++/Library 2021. 3. 10. 21:10

데이터 타입 확인

  • <typeinfo> 라이브러리의 typeid().name()을 사용한다.

      cout << typeid(4.0).name() << endl;  // double

'C++ > Library' 카테고리의 다른 글

C++ cin.ignore  (0) 2021.03.11
C++ cin  (0) 2021.03.11
C++ 난수 생성 (Random Number Generation)  (0) 2021.03.11
C++ 입력 버퍼 무시하기  (0) 2021.03.10
C++ 출력 버퍼 비우기  (0) 2021.03.10
C++/Library 2021. 3. 10. 21:00

출력 버퍼 비우기 (fflush)

std::cout << std::flush;

'C++ > Library' 카테고리의 다른 글

C++ cin.ignore  (0) 2021.03.11
C++ cin  (0) 2021.03.11
C++ 난수 생성 (Random Number Generation)  (0) 2021.03.11
C++ 입력 버퍼 무시하기  (0) 2021.03.10
C++ typeinfo  (0) 2021.03.10

'C++/Library'에 해당되는 글 51건