美文网首页
C++11自定义 std::unique_ptr智能指针

C++11自定义 std::unique_ptr智能指针

作者: FredricZhu | 来源:发表于2022-01-25 14:42 被阅读0次

库里面有现成的智能指针,在memory头文件里面,叫std::unique_ptr。平时工程还是优先选用标准库吧。
这个自定义实现可以帮助理解智能指针的原理,就是RAIL(资源获取即初始化),使用栈对象来管理堆内存。
代码如下,

CMakeLists.txt

cmake_minimum_required(VERSION 2.6)

if(APPLE)
    message(STATUS "This is Apple, do nothing.")
elseif(UNIX)
    message(STATUS "This is linux, set CMAKE_PREFIX_PATH.")
    set(CMAKE_PREFIX_PATH /vcpkg/ports/cppwork/vcpkg_installed/x64-linux/share)
endif(APPLE)

project(holder)

add_definitions(-std=c++17)

add_definitions(-g)

find_package(ZLIB)

find_package(glog REQUIRED)

find_package(OpenCV REQUIRED )

find_package(Boost REQUIRED COMPONENTS
    system
    filesystem
    serialization
    program_options
    thread
    )

find_package(DataFrame REQUIRED)

if(APPLE)
    MESSAGE(STATUS "This is APPLE, set INCLUDE_DIRS")
set(INCLUDE_DIRS ${Boost_INCLUDE_DIRS} /usr/local/include /usr/local/iODBC/include /opt/snowflake/snowflakeodbc/include/ ${CMAKE_CURRENT_SOURCE_DIR}/../../include/ {CMAKE_CURRENT_SOURCE_DIR}/../)
elseif(UNIX)
    MESSAGE(STATUS "This is linux, set INCLUDE_DIRS")
    set(INCLUDE_DIRS ${Boost_INCLUDE_DIRS} /usr/local/include ${CMAKE_CURRENT_SOURCE_DIR}/../../include/ ${CMAKE_CURRENT_SOURCE_DIR}/../)
endif(APPLE)


if(APPLE)
    MESSAGE(STATUS "This is APPLE, set LINK_DIRS")
    set(LINK_DIRS /usr/local/lib /usr/local/iODBC/lib /opt/snowflake/snowflakeodbc/lib/universal)
elseif(UNIX)
    MESSAGE(STATUS "This is linux, set LINK_DIRS")
    set(LINK_DIRS ${Boost_INCLUDE_DIRS} /usr/local/lib /vcpkg/ports/cppwork/vcpkg_installed/x64-linux/lib)
endif(APPLE)

if(APPLE)
    MESSAGE(STATUS "This is APPLE, set ODBC_LIBS")
    set(ODBC_LIBS iodbc iodbcinst)
elseif(UNIX)
    MESSAGE(STATUS "This is linux, set LINK_DIRS")
    set(ODBC_LIBS odbc odbcinst ltdl)
endif(APPLE)

include_directories(${INCLUDE_DIRS})
LINK_DIRECTORIES(${LINK_DIRS})

file( GLOB main_file_list ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) 

file( GLOB APP_SOURCES  ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/../../include/http/impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../include/yaml/impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../include/df/impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../include/death_handler/impl/*.cpp)

add_library(${PROJECT_NAME}_lib SHARED ${APP_SOURCES})
target_link_libraries(${PROJECT_NAME}_lib ${Boost_LIBRARIES} ZLIB::ZLIB glog::glog DataFrame::DataFrame ${OpenCV_LIBS})
target_link_libraries(${PROJECT_NAME}_lib  ssl crypto libgtest.a pystring libyaml-cpp.a libgmock.a ${ODBC_LIBS} libnanodbc.a pthread dl backtrace)

foreach( main_file ${main_file_list} )
    file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${main_file})
    string(REPLACE ".cpp" "" file ${filename})
    add_executable(${file}  ${main_file})
    target_link_libraries(${file} ${PROJECT_NAME}_lib)
endforeach( main_file ${main_file_list})

holder.hpp

#ifndef _FREDRIC_HOLDER_HPP_
#define _FREDRIC_HOLDER_HPP_

#include <algorithm>

template <typename T>
class Holder {
    private:
        T* ptr;
    
    public:
        // 默认构造函数,将 ptr初始化为nullptr
        Holder(): ptr(nullptr) {}

        // 带指针的构造函数,将ptr初始化为一个指针
        Holder(T* p): ptr(p) {}
        
        // 析构函数,删除持有的指针
        ~Holder() {
            delete ptr;
            ptr = nullptr;
        }

        // 赋值为一个新的指针
        Holder<T>& operator=(T* p) {
            delete ptr;
            ptr = p;
            return *this;
        } 

        // 指针操作符重载
        T& operator*() const {
            return *ptr;
        }

        // 指向操作符重载
        T* operator->() const {
            return ptr;
        }

        // 获取引用的对象
        T* get() const {
            return ptr;
        }

        // 释放引用对象的所有权
        void release() {
            delete ptr;
            ptr = nullptr;
        }

        // 和其他Holder对象交换所有权
        void exchange_with(Holder<T>& h) {
            std::swap(ptr, h.ptr);
        }

        void exchange_with(T* & p) {
            std::swap(ptr, p);
        }

        //不允许拷贝和拷贝赋值
        Holder(Holder<T> const& other) = delete;
        Holder<T>& operator=(Holder<T> const& other) = delete;

};
#endif

main.cpp

#include "holder.hpp"
#include <iostream>

class Something {
    public:
        void perform() const {
            std::cout << "Perform..." << std::endl;
        }
};

void do_two_things() {
    Holder<Something> first{new Something};
    first->perform();

    Holder<Something> second{new Something};
    second->perform();
}

int main(int argc, char* argv[]) {
    do_two_things();

    return EXIT_SUCCESS;
}

程序输出如下,


image.png

相关文章

网友评论

      本文标题:C++11自定义 std::unique_ptr智能指针

      本文链接:https://www.haomeiwen.com/subject/qlenhrtx.html