[C++ series notes] 05 C++ type conversion, exception handling, I/O stream

Supplementary knowledge

C++ type conversion

Static conversionstatic_cast<>()

Allows conversion of pointers, references and ordinary variables

  • Basic type

    double b = static_cast<double>(a);
    
  • Custom type

    // 向下转换 不安全
    Child* child = static_cast<Child*>(base);
    
    // 向上转换 安全
    Base& base = static_cast<Base&>(child);
    

    Only allow conversion between parent and child classes, conversion to other types will report an error

Dynamic conversiondynamic_cast<>()

Only pointers and references are allowed to be converted

  • Basic type

    Conversion of basic types is not allowed, the following code is wrong:

    double b = dynamic_cast<double>(a);
    
  • Custom type

    Only allow conversion between father and child,

    Up conversion is allowed or polymorphic conversion has occurred.

    • Up conversion: (always allowed)

      Base& base = dynamic_cast<Base&>(child);
      
    • Down conversion: (not allowed)

    • Polymorphism occurs: (allowed)

      class Base{
              
              
         public:
          virtual void method();
      };
      class Child: public Base{
              
              
         public:
          virtual void method();
      };
      
      // 多态
      Base* base = new Child;
      Child* child = dynamic_cast<Child*>(base);
      

Constant conversionconst_cast<>()

Only pointers and references are allowed to be converted

The rules for basic types and custom types are the same.

  • Remove constmodification

    const int* p;
    int* p1 = const_cast<int*>(p);
    
  • Add constdecoration

    int& ref;
    const int& ref1 = const_cast<const int&>(ref);
    

Reinterpret conversionreinterpret_cast<>()

It is almost never used.

The syntax is the same, can be converted arbitrarily, and there is no security.

C++ exception handling

Basic grammar

  • Keywords:try catch throw

  • Throw an exception

    void fun(){
          
          
        // ...
        if (/* condition */){
          
          
            throw error;
        }
    }
    
  • Catch exception

    Catch a certain type of exception

    try {
          
          
        // 调用
    } catch (int error) {
          
          
        // 处理
    } catch (char error){
          
          
        // 处理
    }
    

    Catch various exceptions

    try {
          
          
        // 调用
    } catch (...) {
          
          
        // 处理
    }
    

    The exception must be caught, otherwise the terminateinterrupt routine will be called automatically .

    If you don't want to deal with it, you can catch it and continue to throw it to the caller.

Basic exception handling

  • Stack unspin

    That is, the objects on the stack will be released before the exception is thrown.

  • Exceptional interface declaration

    Tell the caller in a declarative way whether the interface will throw an exception and what type of exception will be thrown.

    • The following example shows that the interface only throws intand doubletype exceptions.

      int fun() throw(int, double){
              
              
          // ...
      }
      
    • You can also declare that the interface will not throw any exceptions:

      int fun() throw(){
              
              
          // ...
      }
      
  • The life cycle of abnormal variables

    Throwing reference: the whole process from throwing an exception to catching it and handling it.

    Throw value: the entire process from throwing an exception to catching the exception and handling it, but it adds overhead.

    Throw pointer: the pointed data is released before it is captured and processed. At this time, you can open up space for storage in the heap area, but there is a risk of memory leaks.

    References are generally thrown

  • Exception class

    You can define an exception class for throwing, identifying and handling exceptions.

    class Exception{
          
          
        // ...
    };
    
  • Exceptions in polymorphism

    class Exception{
          
          
       public:
        virtual string getMessage() = 0;
    };
    // 继承
    class OutOfRangeException: public Exception{
          
          
       public:
        virtual string getMessage(){
          
          
         	return string("越界异常");   
        }
    };
    
    void fun(){
          
          
    	// ...
        if(/* condition */){
          
          
            // 抛出异常
            throw OutOfRangeException();
        }
    }
    
    int main(){
          
          
        try {
          
          
            fun();
        } catch(Exception& error) {
          
          
            // 多态
            cout << error.getMessage() << endl;
        }
    }
    

C++ Standard Exception Library

The C++ standard library provides an exception classexception

#include <stdexcept>

  • use

    The caught exception object has a whatmethod that returns the character information passed by the thrower.

    void fun() {
          
          
    	throw std::out_of_range("nmsl, cnm.");
    }
    int main() {
          
          
        try {
          
          
            fun();
        } catch (std::out_of_range& error) {
          
          
            cout << error.what() << endl;
        }
    }
    

    You can also catch exceptions through polymorphism:

    try {
          
          
        fun();
    } catch (std::exception& error) {
          
          
        cout << error.what() << endl;
    }
    
  • inherit

    Inherit the exception classes provided by the standard library

    class Exception {
          
          
       private:
        string message;
       public:
        Exception(string message): message(message){
          
          }
        // 重写 what
        virtual const char* what() const{
          
          
            return this->message.c_str;
        }
    }
    

C ++ I / O style

basic introduction

  • Inheritance of C++ I/O

I

There is also: String I/O stream strstreamFile I/O streamfstream

  • cout, cerrAndclog

    • cout(console output)

      cout is the standard output stream. In addition to outputting information to the terminal, it can also output to a disk file.

    • cerr (console error)

      cerr is the standard error stream, it will not pass through the buffer, nor is it allowed to output to a file.

    • clog(console log)

      clog is also the standard error stream, but it passes through the buffer.

Standard input stream

Several important interfaces:

cin.get();                          // 输入一个字符
cin.get(char* buffer, int length);  // 输入一个字符串
cin.getline(char*);                 // 输入一个字符串
cin.ignore(char);                   // 忽略即将读入的字符
cin.peek();                         // 查看/偷窥 即将读入的字符

cin.fail();    // 获取错误状态
cin.clear();   // 重置错误状态
cin.sync();    // 清空缓冲区(存在问题)
  • cin.get

    int cin.get();
    

    There is getchar()no difference between reading one character at a time .

    istream& get(char* buffer, int length);
    

    Read a string of characters at a time and store them in continuous memory. Do not read the trailing newline \n, leave it in the buffer, and will not stop when it encounters a space.

  • cin.ignore

    istream& ignore(int count = 1);
    

    Discard/ignore the countcharacters read immediately .

    istream& ignore(int count, char c);
    

    Character discarded until the number reaches countone, or current discarded characters cthe same.

  • cin.getline

    istream& getline(char* buffer, int length);
    

    Read a string of characters at a time and store them in continuous memory. Read the newline at the end \n, but will not be read into the memory, but directly discarded, and will not stop when encountering a space.

  • cin.peek

    int peek();
    

    Peeping, that is, read in a character and put it back.

  • cin.putback

    istream& putback(char c);
    

    Put the character stored in c at the head of the input buffer, that is, the next character read.

  • cin.fail

    bool fail();
    

    Used to get the error status of cin. Return 0 means no error occurred, 1 means error occurred.

    For example, if the user enters a character other than 0-9, and I receive it through an int, an error will occur.

  • cin.clear

    Used to reset the error state of cin.

  • cin.sync

    Used to clear the buffer, but the implementation on some compilers does not clear the buffer.

    For example, vc++ 2019.

    To empty the buffer, you can do this:

    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    

Standard output stream

Several interfaces: (just understand)

cout.flush();                               // 清空输出缓冲区
cout.put(char c);                           // 向缓冲区写一个字符
cout.write(char* buffer, int length);       // 向缓冲区写一个字符串
  • Formatted output

    cout.width(int width);             // 输出长度
    cout.fill(char c);                 // 多余宽度通过 c 填充
    cout.setf(ios::_Fmtflags flags);   // 设置格式
    cout.unsetf(ios::_Fmtflags flags); // 写在格式
    cout.precision(int n);             // 设置实数精度为 n
    

    Regarding cout.setf, it can also format the output through the control character:

    Include a header file:

    #include<iomanip>
    
    cout << setw(int width) // 输出长度
         << setfill(char c) // 多余宽度通过 c 填充
         << setiosflags(ios::_Fmtflags flags) // 设置格式
         << hex // 16 // 设置格式
         << oct // 8  // 设置格式
         << dec // 10 // 设置格式
         << endl;
    

    The more commonly used parameters are as follows:

    Sign Description
    ios::left Left-justified output
    ios::right Right-justified output
    ios::internal Left-justified sign bit, right-justified value, middle padding
    ios::dec Decimal
    ios::oct Octal
    ios::hex Hexadecimal
    ios :: showbase Output leading character '0x' or '0'
    ios::showpointer Force the decimal point and mantissa of floating point numbers to be output 0
    ios::showpos Display + sign for positive numbers
    ios::scientific Floating point numbers are output in scientific notation format
    ios::fixed Floating point numbers are output in fixed-point format (decimal format)
    ios::unitbuf Flush all streams after each output
    ios::stdio Clear stdout stderr after each output

File I/O flow

head File:

#include <fstream>
  • open a file

    When instantiating:

    ofstream ofs(const char* filename,ios::openmode _Mode );
    

    After instantiation:

    ofstream ofs;
    ofs.open(const char* filename,ios::openmode _Mode );
    

    test:

    if (!ofs.is_open()){
          
          
        // ...
    }
    

    About openmode:

    the way Description
    ios::in enter
    ios::out Output (default method), clear the content if the file already exists
    ios::app Output, appended at the end
    ios::ate Open an existing file, the file pointer points to the end of the file
    ios::trunc Open a file, clear the data if the file exists, create a new file if the file does not exist
    ios::binary Open the file in binary mode
    ios::nocreate Open an existing file, if the file does not exist, the open fails
    ios::noreplace Create a file, if the file already exists, it will fail to open
    ios::in | ios::out Read and write
    ios::out | ios::binary Open an output file in binary mode
    ios::in | ios::binary Input file when opening one in binary mode
  • Write file

    ofstream ofs("./write.txt", ios::out);
    ofs << "test" << endl;
    ofs.close();
    
  • Read file

    ifstream ifs("./read.txt", ios::in);
    
    char buf[1024];
    while (ifs >> buf) {
          
          
        cout << buf << endl;
    }
    
    ifstream ifs("./read.txt", ios::in);
    
    char buf[1024];
    while (!ifs.eof()) {
          
          
        ifs.getline(buf, sizeof(buf));
        cout << buf << endl;
    }
    
    ifstream ifs("./read.txt", ios::in);
    
    char c;
    while (!ifs.eof()) {
          
          
        c = ifs.get();
        cout << c;
    }
    
    // 或者
    while ( (c = ifs.get()) != EOF ) {
          
          
        cout << c;
    }
    

String I/O stream

head File:

#include <sstream>

You can pass data and retrieve data to a stream.

stringstream stream;
// 获取一个流

stream << "123";
// 向流中推送数据

stream >> var;
// 向流流中拿取数据

Application: Convert any basic type

template <class resultType, class paramType >
resultType transform(paramType input) {
    
    
  stringstream stream;
  resultType output;
  stream << input;
  stream >> output;
  return output;
}

E.g:

int output = transform<int>("123");
cout << output;
// > 123

Guess you like

Origin blog.csdn.net/qq_16181837/article/details/106678232