.*、->* 和 .-> 在C++中是什么意思?
What does .*, ->* and .-> mean in C++?
我最近一直在学习如何使用std::mem_fn
图书馆工具。在入门第5版C++中,他们给出了一个std::mem_fn
用法的例子,在下面的代码片段中svec
是string
vector
:
auto f = mem_fn(&string::empty); // f takes a string or a string*
f(*svec.begin()); // ok: passes a string object; f uses .* to call empty
f(&svec[0]); // ok: passes a pointer to string; f uses .-> to call empty
注意:在上面的代码片段中没有使用 ->*
虽然我了解.*
和->*
的用法.我不清楚。
所以,我的问题是.*
,->*
,.->
做什么?
你有一个对象o
和一个指向其成员m
的指针。运算符.*
允许您访问对象的尖头成员:
o.*m
您有一个指向对象p
的指针和一个指向其成员m
的指针。运算符->*
允许您访问指向对象的指向构件:
p->*m
恐怕运算符.->
不存在。
运算符.*
并->*
调用成员函数(顺便说一句,.->
在C++中没有意义 - 这是一个语法错误(。
这些是二元运算符。左操作数是对象(对于.*
(或指向对象的指针(对于->*
(,右操作数是指向成员(可以是成员字段或成员函数(的指针。应用此运算符的结果是能够使用成员字段或方法。
也许从历史的角度来看,这些运算符是有意义的。假设您使用指向函数的常规 C 指针:
typedef int (*CalcResult)(int x, int y, int z);
CalcResult my_calc_func = &CalcResult42;
...
int result = my_calc_func(11, 22, 33);
如果您决定以面向对象的方式"重写"程序怎么办?您的计算函数将是类中的方法。要创建指向它的指针,您需要一个新类型,即指向成员函数的指针:
typedef int (MyClass::*CalcResult)(int x, int y, int z);
CalcResult my_calc_func = &MyClass::CalcResult42;
...
MyClass my_object;
int result = (my_object.*my_calc_func)(11, 22, 33);
当我尝试记住这个.*
运算符的语法时,我总是使用这个类比 - 这很有帮助,因为常规指针到函数语法不那么复杂并且使用更频繁。
请注意括号:
int result = (my_object.*my_calc_func)(11, 22, 33);
使用此.*
运算符时几乎总是需要它们,因为它的优先级较低。即使my_object .* (my_calc_func(11, 22, 33))
毫无意义,如果没有括号,编译器也会尝试理解它。
->*
运算符的工作方式基本相同。如果要应用该方法的对象由指针给出,则将使用它:
typedef int (*MyClass::CalcResult)(int x, int y, int z);
CalcResult my_calc_func = &MyClass::CalcResult42;
...
MyClass my_object1, my_object2;
MyClass* my_object = flag ? &my_object1 : &my_object2;
int result = (my_object->*my_calc_func)(11, 22, 33);
.*
和 ->*
运算符称为指向成员访问运算符的指针,就像它们的名字一样,它们允许您访问对象的数据或函数成员,给定指向该类成员的适当指针。
struct foo
{
int a;
float b;
void bar() { std::cout << "barn"; }
};
int main()
{
int foo::* ptra = &foo::a;
float foo::* ptrb = &foo::b;
void (foo::* ptrbar)() = &foo::bar;
foo f;
foo * fptr = &f;
f.*ptra = 5;
f.*ptrb = 10.0f;
(f.*ptrbar)();
fptr->*ptra = 6;
fptr->*ptrb = 11.0f;
(fptr->*ptrbar)();
return 0;
}
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 使用 std::vector<boost::shared_ptr<Base_Class>> 或 boost::p tr_vector 的性能注意事项是什么<Base>