箭头运算符(->)是指针访问成员的语法糖,它等价于先解引用再访问成员。通过重载箭头运算符,我们可以让自定义类型表现得像指针一样,这在实现智能指针和迭代器时非常有用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include <iostream>
class Entity
{
public:
void Print() const { std::cout << "Hello!" << std::endl; }
int value = 42;
};
int main()
{
Entity e;
e.Print(); // 直接访问成员
Entity* ptr = &e;
ptr->Print(); // 箭头运算符访问成员
(*ptr).Print(); // 等价写法:先解引用再访问成员
std::cout << "ptr->value = " << ptr->value << std::endl;
std::cout << "(*ptr).value = " << (*ptr).value << std::endl;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
class SmartPtr
{
private:
Entity* m_Entity;
public:
SmartPtr(Entity* entity) : m_Entity(entity) {}
~SmartPtr() { delete m_Entity; }
// 传统方式:需要调用GetObject()
const Entity* GetObject() const { return m_Entity; }
// 重载箭头运算符
const Entity* operator->() const { return m_Entity; }
// 非const版本
Entity* operator->() { return m_Entity; }
};
int main()
{
{
SmartPtr sptr(new Entity());
// 传统方式:不够优雅
sptr.GetObject()->Print();
// 使用重载的箭头运算符:更优雅
sptr->Print();
sptr->value = 100;
std::cout << "Value: " << sptr->value << std::endl;
} // SmartPtr析构,自动删除Entity
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
template<typename T>
class UniquePtr
{
private:
T* m_Ptr;
public:
explicit UniquePtr(T* ptr) : m_Ptr(ptr) {}
~UniquePtr()
{
delete m_Ptr;
}
// 禁用拷贝
UniquePtr(const UniquePtr&) = delete;
UniquePtr& operator=(const UniquePtr&) = delete;
// 移动构造函数
UniquePtr(UniquePtr&& other) noexcept : m_Ptr(other.m_Ptr)
{
other.m_Ptr = nullptr;
}
// 移动赋值运算符
UniquePtr& operator=(UniquePtr&& other) noexcept
{
if (this != &other)
{
delete m_Ptr;
m_Ptr = other.m_Ptr;
other.m_Ptr = nullptr;
}
return *this;
}
// 箭头运算符
T* operator->() const
{
return m_Ptr;
}
// 解引用运算符
T& operator*() const
{
return *m_Ptr;
}
// 转换为bool
explicit operator bool() const
{
return m_Ptr != nullptr;
}
// 获取原始指针
T* Get() const { return m_Ptr; }
// 释放所有权
T* Release()
{
T* temp = m_Ptr;
m_Ptr = nullptr;
return temp;
}
// 重置指针
void Reset(T* ptr = nullptr)
{
delete m_Ptr;
m_Ptr = ptr;
}
};
class TestClass
{
private:
std::string m_Name;
int m_Value;
public:
TestClass(const std::string& name, int value)
: m_Name(name), m_Value(value)
{
std::cout << "Create " << m_Name << std::endl;
}
~TestClass()
{
std::cout << "Destroy " << m_Name << std::endl;
}
void DoSomething() const
{
std::cout << m_Name << " is doing something (value: " << m_Value << ")" << std::endl;
}
void SetValue(int value) { m_Value = value; }
int GetValue() const { return m_Value; }
const std::string& GetName() const { return m_Name; }
};
int main()
{
{
UniquePtr<TestClass> ptr(new TestClass("MyObject", 42));
if (ptr) // 使用operator bool
{
ptr->DoSomething(); // 使用operator->
ptr->SetValue(100); // 使用operator->
(*ptr).DoSomething(); // 使用operator*
std::cout << "Value: " << ptr->GetValue() << std::endl;
}
} // ptr离开作用域,TestClass自动销毁
std::cout << "UniquePtr destroyed" << std::endl;
}
|
箭头运算符可以链式调用,编译器会递归地应用箭头运算符:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
class Wrapper
{
private:
UniquePtr<TestClass> m_Ptr;
public:
Wrapper(TestClass* obj) : m_Ptr(obj) {}
// 返回UniquePtr的引用
UniquePtr<TestClass>& operator->()
{
return m_Ptr;
}
const UniquePtr<TestClass>& operator->() const
{
return m_Ptr;
}
};
int main()
{
Wrapper wrapper(new TestClass("Wrapped", 123));
// 链式箭头运算符调用:
// wrapper-> 返回 UniquePtr<TestClass>&
// UniquePtr<TestClass>& -> 返回 TestClass*
// TestClass* -> 访问成员
wrapper->DoSomething();
wrapper->SetValue(456);
std::cout << "Final value: " << wrapper->GetValue() << std::endl;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
template<typename T>
class SimpleVector
{
private:
T* m_Data;
size_t m_Size;
size_t m_Capacity;
public:
SimpleVector() : m_Data(nullptr), m_Size(0), m_Capacity(0) {}
~SimpleVector()
{
delete[] m_Data;
}
void PushBack(const T& item)
{
if (m_Size >= m_Capacity)
{
m_Capacity = m_Capacity == 0 ? 1 : m_Capacity * 2;
T* newData = new T[m_Capacity];
for (size_t i = 0; i < m_Size; ++i)
newData[i] = m_Data[i];
delete[] m_Data;
m_Data = newData;
}
m_Data[m_Size++] = item;
}
// 简单的迭代器实现
class Iterator
{
private:
T* m_Ptr;
public:
Iterator(T* ptr) : m_Ptr(ptr) {}
// 箭头运算符
T* operator->() const
{
return m_Ptr;
}
// 解引用运算符
T& operator*() const
{
return *m_Ptr;
}
// 前置递增
Iterator& operator++()
{
++m_Ptr;
return *this;
}
// 比较运算符
bool operator!=(const Iterator& other) const
{
return m_Ptr != other.m_Ptr;
}
};
Iterator begin() { return Iterator(m_Data); }
Iterator end() { return Iterator(m_Data + m_Size); }
};
class Person
{
private:
std::string m_Name;
int m_Age;
public:
Person(const std::string& name, int age) : m_Name(name), m_Age(age) {}
void Introduce() const
{
std::cout << "Hi, I'm " << m_Name << ", " << m_Age << " years old." << std::endl;
}
const std::string& GetName() const { return m_Name; }
int GetAge() const { return m_Age; }
};
int main()
{
SimpleVector<Person> people;
people.PushBack(Person("Alice", 25));
people.PushBack(Person("Bob", 30));
people.PushBack(Person("Charlie", 35));
std::cout << "Using iterator with arrow operator:" << std::endl;
for (auto it = people.begin(); it != people.end(); ++it)
{
it->Introduce(); // 使用迭代器的箭头运算符
std::cout << "Age: " << it->GetAge() << std::endl;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
class ArrowTest
{
private:
int m_Value;
public:
ArrowTest(int value) : m_Value(value) {}
void Print() const
{
std::cout << "Value: " << m_Value << std::endl;
}
int GetValue() const { return m_Value; }
};
class ArrowProxy
{
private:
ArrowTest* m_Target;
public:
ArrowProxy(ArrowTest* target) : m_Target(target) {}
// 箭头运算符必须返回指针或者重载了箭头运算符的对象
ArrowTest* operator->() const
{
std::cout << "ArrowProxy::operator-> called" << std::endl;
return m_Target;
}
};
class ArrowChain
{
private:
ArrowProxy m_Proxy;
public:
ArrowChain(ArrowTest* target) : m_Proxy(target) {}
// 返回重载了箭头运算符的对象
ArrowProxy operator->() const
{
std::cout << "ArrowChain::operator-> called" << std::endl;
return m_Proxy;
}
};
int main()
{
ArrowTest test(42);
ArrowProxy proxy(&test);
ArrowChain chain(&test);
std::cout << "=== Direct access ===" << std::endl;
test.Print();
std::cout << "\n=== Through proxy ===" << std::endl;
proxy->Print();
std::cout << "\n=== Through chain ===" << std::endl;
chain->Print(); // 会依次调用ArrowChain::operator->和ArrowProxy::operator->
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
class Subject;
class Observer
{
public:
virtual void Update(const Subject* subject) = 0;
virtual ~Observer() = default;
};
class Subject
{
private:
std::vector<Observer*> m_Observers;
int m_State;
public:
Subject(int state) : m_State(state) {}
void Attach(Observer* observer)
{
m_Observers.push_back(observer);
}
void SetState(int state)
{
m_State = state;
NotifyAll();
}
int GetState() const { return m_State; }
private:
void NotifyAll()
{
for (Observer* observer : m_Observers)
{
observer->Update(this);
}
}
};
// 智能观察者指针
class ObserverPtr
{
private:
Observer* m_Observer;
Subject* m_Subject;
public:
ObserverPtr(Observer* observer, Subject* subject)
: m_Observer(observer), m_Subject(subject)
{
if (m_Subject)
m_Subject->Attach(m_Observer);
}
Observer* operator->() const
{
return m_Observer;
}
Observer& operator*() const
{
return *m_Observer;
}
};
class ConcreteObserver : public Observer
{
private:
std::string m_Name;
public:
ConcreteObserver(const std::string& name) : m_Name(name) {}
void Update(const Subject* subject) override
{
std::cout << m_Name << " received update: state = "
<< subject->GetState() << std::endl;
}
void DoSomething()
{
std::cout << m_Name << " is doing something" << std::endl;
}
};
int main()
{
Subject subject(0);
ObserverPtr obs1(new ConcreteObserver("Observer1"), &subject);
ObserverPtr obs2(new ConcreteObserver("Observer2"), &subject);
obs1->DoSomething(); // 使用箭头运算符
obs2->DoSomething();
subject.SetState(10);
subject.SetState(20);
}
|
- 箭头运算符本质:指针访问成员的语法糖,等价于先解引用再访问成员
- 重载用途:让自定义类型表现得像指针一样,常用于智能指针和迭代器
- 返回类型:必须返回指针或者重载了箭头运算符的对象
- 链式调用:编译器会递归地应用箭头运算符,直到得到真正的指针
- 实际应用:智能指针、迭代器、代理模式等场景中广泛使用