相关知识:
- 箭头操作符
->
(必须定义为类成员函数)和解引用操作符*
(不要求定义为成员)常用在实现智能指针的类中。 - 类成员访问运算符(
->
)可以被重载,但它较为麻烦。它被定义用于为一个类赋予”指针”行为。运算符->
必须是一个成员函数。如果使用了->
运算符,返回类型必须是指针或者是类的对象。 - 运算符
->
通常与指针引用运算符*
结合使用,用于实现”智能指针”的功能。这些指针是行为与正常指针相似的对象,唯一不同的是,当您通过指针访问对象时,它们会执行其他的任务。比如,当指针销毁时,或者当指针指向另一个对象时,会自动删除对象。
运算符->
的重载比较特别,它只能是非静态的成员函数形式,而且没有参数。
- 1、如果返回值是一个原始指针,那么就将运算符的右操作数当作这个原始指针所指向类型的成员进行访问;
- 2、如果返回值是另一个类型的实例,那么就继续调用这个返回类型的
operator->()
,直到有一个调用返回一个原始指针为止,然后按第一种情况处理。
例如:函数语句为:a->b;
(其中,b可以是函数或者成员;) - 步骤1. 如果a是指针,指向一个具有成员b的类对象,那么
a->b
返回a类型的成员b,至此,语句结束; - 步骤2. 如果a是一个对象(对象必须重定义了“
operator->
”,否则报错),那么就调用a的operator->()
函数,返回值:如果是指针则继续执行步骤1,如果是对象则继续执行步骤2,直到最终走到指针结束。代码相关内容:
- 成员访问操作符:解引用操作符:
*
;和箭头操作符:->
。 - 管理指针成员(定义智能指针类,只有在使用智能指针类的时候可能需要重载成员访问操作符)。
string.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class String
{
public:
String(char const *chars = "");
String(String const &str);
~String();
void display() const;
private:
char *ptrChars;
};string.cpp:
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
String::String(char const *chars)
{
// 如果是空指针就变为空字符串;
chars = chars ? chars : "";
ptrChars = new char[std::strlen(chars) + 1];
std::strcpy(ptrChars, chars);
}
String::String(String const &str)
{
ptrChars = new char[std::strlen(str.ptrChars) + 1];
std::strcpy(ptrChars, str.ptrChars);
}
String::~String()
{
delete[] ptrChars;
}
void String::display() const
{
std::cout << ptrChars << std::endl;
}pointer.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 避免重定义:比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。
class String;
// 智能指针:对指针使用进行计数;
class Pointer
{
public:
Pointer();
Pointer(String const &n);
~Pointer();
String &operator*();
String *operator->() const;
private:
String *ptr;
static String errorMessage;
};pointer.cpp:
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
Pointer::Pointer() : ptr(0) {}
Pointer::Pointer(String const &n)
{
ptr = new String(n);
}
Pointer::~Pointer()
{
delete ptr;
}
String Pointer::errorMessage("Uninitialized pointer.");
String &Pointer::operator*()
{
if (!ptr)
throw errorMessage;
return *ptr;
}
String *Pointer::operator->() const
{
if (!ptr)
throw errorMessage;
return ptr;
}main.cpp:
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
using namespace std;
int main()
{
String s("Hello String");
s.display();
String *ps = &s;
ps->display();
try
{
Pointer p1("C++");
p1->display();
String s = *p1;
s.display();
Pointer p2;
p2->display();
}
catch (String const &error)
{
error.display();
}
cout << "Hello HTL2018" << endl;
return 0;
}代码执行结果:
参考链接:
c,c++里面,头文件里面的ifndef /define/endif的作用
C++ 类成员访问运算符 -> 重载
成员访问(->)操作符的重载