库里面有现成的智能指针,在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
网友评论