重载赋值运算符与构造配对出现
C++ 非常重要的两个构造,拷贝构造和移动构造。
分别对应拷贝赋值和移动赋值。请同时出现让外部人员认为行为的一致。
class SimpleVector {
private:
int m_size;
int* m_data;
public:
SimpleVector(int len) : m_size(len), m_data(new int[len]{}) {
}
~SimpleVector() {
if (m_data != nullptr) {
delete[] m_data;
m_data = nullptr;
m_size = 0;
}
}
public:
// 拷贝
SimpleVector(const SimpleVector& rhs) {
this->m_size = rhs.m_size;
this->m_data = new int[this->m_size];
for (int i = 0; i < this->m_size; i += 1) {
this->m_data[i] = rhs.m_data[i];
}
}
SimpleVector& operator=(const SimpleVector& rhs) {
this->~SimpleVector();
this->m_size = rhs.m_size;
this->m_data = new int[this->m_size];
for (int i = 0; i < this->m_size; i += 1) {
this->m_data[i] = rhs.m_data[i];
}
return *this;
}
// 移动
SimpleVector(SimpleVector&& rhs) {
this->m_size = rhs.m_size;
this->m_data = rhs.m_data;
rhs.m_size = 0;
rhs.m_data = nullptr;
}
SimpleVector& operator=(SimpleVector&& rhs) {
this->m_size = rhs.m_size;
this->m_data = rhs.m_data;
rhs.m_size = 0;
rhs.m_data = nullptr;
return *this;
}
};
重载 operator new 和 delete 配对出现
就像是在工厂模式中一样,有构造工厂的同时要提供析构工厂。
class Node {
public:
int x;
Node(int x) : x(x) {
}
public:
static void* operator new(size_t size) {
// 调用全局的 operator new
return ::operator new(size);
}
static void operator delete(void* ptr) {
// 调用全局的 ::operator delete
::operator delete(ptr);
}
};
考虑const 左右值重载
一般对应左右值重载的情况不多,此处以 const 重载为例。
class SimpleVector {
private:
int m_size;
int* m_data;
public:
SimpleVector(int len) : m_size(len), m_data(new int[len]{}) {
}
~SimpleVector() {
if (m_data != nullptr) {
delete[] m_data;
m_data = nullptr;
m_size = 0;
}
}
public:
// const 版本重载
const int& operator[](int index) const {
return m_data[index];
}
谨慎返回静态对象
使用静态对象可以减少临时对象的生成,但是提升效率的同时往往会造成许多意想不到的问题。
#include <iostream>
class Node {
public:
int x;
Node(int x) : x(x) {
}
public:
bool operator==(const Node& rhs) {
std::cout << "this=" << this << " rhs=" << &rhs << std::endl;
return this->x == rhs.x;
}
};
Node& operator+(const Node& lhs, const Node& rhs) {
static Node pub(0);
pub.x = lhs.x + rhs.x;
return pub;
}
int main() {
Node a(10);
Node b(20);
Node c(30);
Node d(40);
// 减少了临时对象的生成
a + b;
c + d;
// 不是我们理想的效果
谨慎重载类型
C++ 支持类型的重载,使得外部在调用对象的时候能够在某些情况下达到使用类似目标类型的效果。
