针对C++异常的学习

源码 头文件  sdf_exception.h

#pragma once

#include <exception>
#include <string>

namespace sdf {
    namespace common{

        using sdf_error_code_t = uint32_t;
        class SdfException : std::exception{
        public:
            explicit SdfException(sdf_error_code_t errorCode) : error_code(error_code){};
            SdfException(sdf_error_code_t errorCode,std::string error_message){}
            SdfException(sdf_error_code_t x,sdf_error_code_t y,sdf_error_code_t z):error_code(pack211(x,y,z)){}
            SdfException(sdf_error_code_t x,sdf_error_code_t y,sdf_error_code_t z,std::string error_message){}

            const char *what() const noexcept override;

            sdf_error_code_t get_error_code() const{
                return error_code;
            }

        public:
            static sdf_error_code_t pack211(sdf_error_code_t x,sdf_error_code_t y,sdf_error_code_t z){
                return x << 16U | y << 8U | z;           //Appending u to any integral constant makes the compiler interpret it as unsigned.
            }
        private:
            sdf_error_code_t error_code;
            std::string error_message;

            bool error_message_packed = false;//< flag for lazy packing error message
        };
    }
}

学习

源文件  sdf_exception.cpp

#include "sdf_exception.h"

#include "logging.h"

namespace sdf {
namespace common {

std::string pack_error_message(sdf_error_code_t error_code,
                               const std::string &error_message) {
  char buffer[1024];
  auto length =
      std::snprintf(buffer, sizeof(buffer), "sdf exception: [0x%08x] %s\n",
                    error_code, error_message.c_str());
  if (length < 0 || length >= static_cast<int>(sizeof(buffer))) {
    log_fatal("Unexpected error message length: %s", length);
  }
  return buffer;
}

SdfException::SdfException(sdf_error_code_t error_code,
                           std::string error_message)
    : error_code(error_code), error_message(std::move(error_message)) {}

SdfException::SdfException(sdf_error_code_t x, sdf_error_code_t y,
                           sdf_error_code_t z, std::string error_message)
    : error_code(pack211(x, y, z)), error_message(std::move(error_message)) {}

const char *SdfException::what() const noexcept {
  if (!error_message_packed) {
    const_cast<bool &>(error_message_packed) = true;
    const_cast<std::string &>(error_message) =
        pack_error_message(error_code, error_message);
  }
  return error_message.c_str();
}

} // namespace common
} // namespace sdf

学习

代码调用

代码层次结构

所需要的配套文件

 logging.h

#pragma once

namespace sdf {
    namespace common {

        enum LogLevel {
            SDF_LOG_DEBUG,
            SDF_LOG_INFO,
            SDF_LOG_WARN,
            SDF_LOG_ERROR,
            SDF_LOG_FATAL,
            SDF_LOG_IMPORTANT_INFO
        };

        void set_logging_level(LogLevel level);

#define LOGGER_DECLARATION(level) void log_##level(const char *format, ...);

        LOGGER_DECLARATION(debug)
        LOGGER_DECLARATION(info)
        LOGGER_DECLARATION(warn)
        LOGGER_DECLARATION(error)
        LOGGER_DECLARATION(fatal)
        LOGGER_DECLARATION(important)

#undef LOGGER_DECLARATION

    } // namespace common
} // namespace sdf

logging.cpp

#include "logging.h"
//#include "sdf_config.h"

#include <cstdarg>
#include <cstdio>
#include <ctime>
#include <mutex>

#ifdef ENABLE_SYSLOG
#include <syslog.h>
#endif

namespace sdf {
    namespace common {

        const char *get_current_time() {
            static char buffer[80];
            time_t raw_time;
            std::time(&raw_time);
            std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S",
                          localtime(&raw_time));

            return buffer;
        }

        class Logger {
        public:
            static inline void set_logging_level(LogLevel level) {
                default_logging_level = level;
            }

#ifndef ENABLE_SYSLOG

            static void vlog(LogLevel level, const char *format, va_list ap) {
                if (level < Logger::default_logging_level) {
                    return;
                }

                auto endpoint = stdout;
                if (level == SDF_LOG_ERROR || level == SDF_LOG_FATAL) {
                    endpoint = stderr;
                }

                const char *level_info = nullptr;
                switch (level) {
                    case SDF_LOG_DEBUG:
                        level_info = "DEBUG";
                        break;
                    case SDF_LOG_INFO:
                    case SDF_LOG_IMPORTANT_INFO:
                        level_info = "INFO";
                        break;
                    case SDF_LOG_WARN:
                        level_info = "WARN";
                        break;
                    case SDF_LOG_ERROR:
                        level_info = "ERROR";
                        break;
                    case SDF_LOG_FATAL:
                        level_info = "FATAL";
                        break;
                    default:
                        break;
                }

                std::lock_guard<std::mutex> lock(log_mutex);

                ::fprintf(endpoint, "[%s][%s] ", get_current_time(), level_info);
                ::vfprintf(endpoint, format, ap);
                ::fprintf(endpoint, "\n");

                if (level == SDF_LOG_FATAL) {
                    ::abort();
                }
            }

#else

            static void vlog(LogLevel level, const char *format, va_list ap) {
    if (level < Logger::default_logging_level) {
      return;
    }

    int syslog_level = 0;
    switch (level) {
    case SDF_LOG_DEBUG:
      syslog_level = LOG_DEBUG;
      break;
    case SDF_LOG_INFO:
      syslog_level = LOG_INFO;
      break;
    case SDF_LOG_IMPORTANT_INFO:
      syslog_level = LOG_NOTICE;
      break;
    case SDF_LOG_WARN:
      syslog_level = LOG_WARNING;
      break;
    case SDF_LOG_ERROR:
      syslog_level = LOG_ERR;
      break;
    case SDF_LOG_FATAL:
      syslog_level = LOG_CRIT;
      break;
    default:
      break;
    }

    // std::lock_guard<std::mutex> lock(log_mutex);

    vsyslog(syslog_level, format, ap);

    if (level == SDF_LOG_FATAL) {
      ::abort();
    }
  }

#endif

            static inline void log(LogLevel level, const char *format, ...) {
                va_list ap;
                        va_start(ap, format);
                vlog(level, format, ap);
                        va_end(ap);
            }

        private:
            static LogLevel default_logging_level;
            static std::mutex log_mutex;
        };

        LogLevel Logger::default_logging_level = LogLevel::SDF_LOG_INFO;
        std::mutex Logger::log_mutex;

        void set_logging_level(LogLevel level) { Logger::set_logging_level(level); }

#define LOGGER_DEFINITION(level, level_tag)                                    \
  void log_##level(const char *format, ...) {                                  \
    va_list ap;                                                                \
    va_start(ap, format);                                                      \
    Logger::vlog(level_tag, format, ap);                                       \
    va_end(ap);                                                                \
  }

        LOGGER_DEFINITION(debug, SDF_LOG_DEBUG)
        LOGGER_DEFINITION(info, SDF_LOG_INFO)
        LOGGER_DEFINITION(warn, SDF_LOG_WARN)
        LOGGER_DEFINITION(error, SDF_LOG_ERROR)
        LOGGER_DEFINITION(fatal, SDF_LOG_FATAL)
        LOGGER_DEFINITION(important, SDF_LOG_IMPORTANT_INFO)

#undef LOGGER_DEFINITION

    } // namespace common
} // namespace sdf

 random_generator.cpp

#include "random_generator.h"

#include "../common/sdf_exception.h"

#include <string>
#include <iostream>

std::string::size_type sdf::sys::GenerateRandom::NDSKeyStore_Common_GenerateRandom( size_t uiLength){

    std::cout << uiLength << std::endl;
    try {
        if(uiLength != 1024)
//            throw common::SdfException(-1);
            throw common::SdfException(45,"There is an error in the program, please solve it immediately!!");
//            throw common::SdfException(1,2,3);
//            throw common::SdfException(1,2,3,"There is an error in the program, please solve it immediately!");
    } catch (common::SdfException& e) {

//        std::cerr<<"ERROR CODE:"<< e.get_error_code() << std::endl;
        std::cerr << e.what() << std::endl;
    }

}

random_generator.h

#pragma once

#include <cstddef>
#include <string>

namespace sdf {
    namespace sys{
        class GenerateRandom {
        public:
            explicit GenerateRandom() = default;
            virtual ~GenerateRandom() = default;
            static std::string::size_type NDSKeyStore_Common_GenerateRandom(size_t uiLength);
        };

    }// namespace sys
}// namespace sdf

main函数调用

#include <iostream>
#include <sstream>

#include "../src/algorithm/random/random_generator.h"
#include "../src/algorithm/common/StringBuffer.h"

#define BUF_SIZE 1024
int main(){

    sdf::sys::GenerateRandom::NDSKeyStore_Common_GenerateRandom(1026);

    return 0;
 }

注意事项:

  • catch不一定需要紧紧跟着try

猜你喜欢

转载自blog.csdn.net/CHYabc123456hh/article/details/109060902