// 双向指针
// 这种用法的缺点是如果在使用者获得指针后,
// 正在使用的时候, 原对象销毁, 可能导致异常.
// 较好的做法是使用 shared_ptr / weak_ptr (#include <memory>)
// 但是需要对象在设计的时候支持.
#include <iostream>
#include <memory>
#include <utility>
#include <vector>
template <typename T1, typename T2>
struct Linked {
friend struct Linked<T2, T1>;
Linked(T2* t) {
other = nullptr;
data = t;
};
public:
~Linked() { Clear(); }
// 清除连接
void Clear() {
data = nullptr;
if (other != nullptr && other->other == this) {
other->data = nullptr;
other->other = nullptr;
other = nullptr;
}
}
bool IsNull() { return other == nullptr; }
T2* operator->() { return data; }
// 构造器
static bool make_linked(T1* t1, std::shared_ptr<Linked<T1, T2>>& ptr1, T2* t2,
std::shared_ptr<Linked<T2, T1>>& ptr2) {
if (t1 == nullptr || t2 == nullptr) {
return false;
}
auto node1 = new Linked<T1, T2>(t2);
auto node2 = new Linked<T2, T1>(t1);
node1->other = node2;
node2->other = node1;
ptr1 = std::shared_ptr<Linked<T1, T2>>(node1);
ptr2 = std::shared_ptr<Linked<T2, T1>>(node2);
return true;
}
private:
Linked<T2, T1>* other;
T2* data;
};
// Test
struct B;
struct A {
A(int d) : data(d) {}
void ShowA() { std::cout << "A: " << data << std::endl; }
std::shared_ptr<Linked<A, B>> pB;
int data;
};
struct B {
B(int d) : data(d) {}
void ShowB() { std::cout << "B: " << data << std::endl; }
std::shared_ptr<Linked<B, A>> pA;
int data;
};
int main() {
auto a = new A(100);
auto b = new B(200);
Linked<A, B>::make_linked(a, a->pB, b, b->pA);
(*a->pB)->ShowB();
(*b->pA)->ShowA();
auto b2 = new B(300);
Linked<A, B>::make_linked(a, a->pB, b2, b2->pA);
(*a->pB)->ShowB();
(*b2->pA)->ShowA();
if (b->pA->IsNull()) {
std::cout << "b->pA == null" << std::endl;
}
return 0;
}
C++双向指针示例
于 2020-05-15 19:51:05 首次发布