在C++中构造函数的种类纷繁复杂. 有默认构造函数, 拷贝构造函数, 移动构造函数和重载的构造函数. 还包括以相关联的赋值函数和移动赋值函数. 下面通过实现一个转移所有权的智能指针
, 一窥构造函数的用法. 下面是具体的例子:
#include <cassert>
#include <iostream>
// 转移所有权智能指针
template <typename T> class smart_pointer {
public:
// 默认构造函数
smart_pointer() noexcept : m_ptr(new T()) {
std::cout << "调用默认构造函数" << std::endl;
}
smart_pointer(const T &ptr) noexcept : m_ptr(new T(ptr)) {
std::cout << "调用重载构造函数" << std::endl;
}
// 拷贝构造函数
smart_pointer(smart_pointer &ptr) noexcept {
std::cout << "调用拷贝构造函数" << std::endl;
m_ptr = ptr.release();
}
// 赋值
smart_pointer &operator=(smart_pointer &ptr) noexcept {
std::cout << "调用赋值函数" << std::endl;
smart_pointer tmp(ptr); // 转移所有权
swap(tmp);
return *this;
}
// 移动构造函数
smart_pointer(smart_pointer &&ptr) noexcept {
std::cout << "调用移动构造函数" << std::endl;
m_ptr = ptr.release();
}
// 移动赋值
smart_pointer &operator=(smart_pointer &&ptr) noexcept {
std::cout << "调用移动赋值函数" << std::endl;
smart_pointer tmp(ptr); // 转移所有权
swap(tmp);
return *this;
}
void swap(smart_pointer &ptr) noexcept { std::swap(m_ptr, ptr.m_ptr); }
// 释放所有权
T *release() noexcept {
T *tmp = m_ptr;
m_ptr = nullptr;
return tmp;
}
T *get() const noexcept { return m_ptr; }
~smart_pointer() {
if (m_ptr)
delete m_ptr;
}
private:
T *m_ptr;
};
template<typename T>
void swap(smart_pointer<T> &lhs, smart_pointer<T> &rhs) noexcept {
lhs.swap(rhs);
}
int main(void) {
// 调用重载构造函数
smart_pointer<std::string> s{"hello world!"};
std::cout << *s.get() << std::endl;
std::cout << std::endl;
// 调用拷贝构造函数
smart_pointer<std::string> s2(s);
std::cout << *s2.get() << std::endl;
assert(s.get() == nullptr);
std::cout << std::endl;
// 调用拷贝构造函数
smart_pointer<std::string> s3 = s2;
std::cout << *s3.get() << std::endl;
assert(s2.get() == nullptr);
std::cout << std::endl;
// 调用默认构造函数
// 调用赋值函数
// 调用拷贝构造函数
smart_pointer<std::string> s4;
s4 = s3;
std::cout << *s4.get() << std::endl;
assert(s3.get() == nullptr);
std::cout << std::endl;
// 调用移动构造函数
smart_pointer<std::string> s5 = std::move(s4);
std::cout << *s5.get() << std::endl;
assert(s4.get() == nullptr);
std::cout << std::endl;
// 调用默认构造函数
// 调用移动赋值函数
// 调用拷贝构造函数
smart_pointer<std::string> s6;
s6 = std::move(s5);
std::cout << *s6.get() << std::endl;
assert(s5.get() == nullptr);
return 0;
}
如果觉得有帮助,可以扫描右边的微信打赏码支持一下.