“.”、“::”和“->”之间的区别

问题描述 投票:0回答:4

在c++中这3块代码有什么区别吗:

MyClass->m_Integer // 1
MyClass::m_Integer // 2
MyClass.m_Integer  // 3
c++ pointers
4个回答
11
投票

->
.
运算符是访问类实例成员的方法,而
::
允许您访问类的静态成员。

->
.
之间的区别在于,箭头用于通过指针访问实例,而点用于访问值(非指针)。

例如,假设您有一个类

MyClass
定义为:

class MyClass
{
public:
    static int someValue();
    int someOtherValue();
};

您将在以下情况下使用这些运算符:

MyClass *ptr = new MyClass;
MyClass value;

int arrowValue = ptr->someOtherValue();
int dotValue = value.someOtherValue();
int doubleColonValue = MyClass::someValue();

在 Java 中,这看起来像:

MyClass ref = new MyClass;

int dotValue = ref.someOtherValue();
int doubleColonValue = MyClass.someValue();

6
投票

-> 表示 MyClass 是指向该类的指针,并且需要取消引用该指针才能获取成员 m_Integer

:: 是范围或命名空间运算符。这意味着 m_Integer 要么是静态的,要么需要您具体确定 m_Integer 位于哪个范围或命名空间内。

。意味着 m_Integer 可以从 MyClass 直接访问(而不是通过指针)。这与您在 Java 中访问成员的方式差不多,并且应该是您最熟悉的一种。


6
投票
  • a::b
    --
    a
    是命名空间或类(不是实例),因此
    b
    需要是某个静态实体
  • a.b
    --
    a
    是类的实例,
    b
    是其成员
  • a->b
    ——与
    (*a).b
    相同(
    a
    是指向类实例的指针)

0
投票

与您获得的其他答案一起,值得注意的是

operator->
可能会超载。您已经获得了关于内置版本如何工作的一些合理解释,但是重载的
operator->
有点不寻常,所以也许值得添加一些关于它如何工作的信息。

该标准相当简洁地描述了

operator->
的异常情况(第 13.5.6 节):

如果 T::operator->() 存在并且该运算符被选为最佳匹配,则对于 T 类型的类对象 x,表达式 x->m 被解释为 (x.operator->())->m通过重载解析机制(13.3)发挥作用。

这有几个含义:

  1. 尽管
    ->
    看起来像一个二元运算符,但从重载的角度来看,它本质上是一个一元运算符——您的重载将是一个不带参数的成员函数。
  2. 您的重载必须返回两种类型之一:要么是(引用)另一个也重载的类的实例
    operator->
    ,要么是指向某个对象(类或结构类型)的指针。

由于您可以返回一个本身重载

operator->
的对象,因此
x->m
形式的表达式可以隐藏任意数量的复杂性(调用任意数量的函数)。你写的
x->m
真的可以扩展到
x->y->z->a->b->...m

© www.soinside.com 2019 - 2024. All rights reserved.