是否存在通过引用选择元素和通过指针操作选择元素都有效的情况



我的背景是使用更多托管语言(C#、python),但我在C/C++方面越来越有经验。我熟悉为什么通过引用进行选择(.)和通过指针操作进行选择(->)运算符不同。在我遇到的所有情况下,如果你使用了不正确的一个,它将导致编译错误。如果是这样的话,他们为什么没有成为一个操作员?是否存在在同一对象上使用任意一个都会产生不同、有意义和有用的结果的情况?

这个问题的灵感来源于这个答案:这是用c++调用函数的正确方法吗?

在C++中,您可以重载->-运算符,它几乎在所有智能指针实现中都使用。然而,其中一些也有自己的方法,即发布引用。

struct test {
    int x;
};
std::shared_ptr<int> ptr(new test);
// Write to member x of the allocated object
ptr->x = 3;
// Reset the shared pointer to point to a different object.
// If there are no further shared_ptrs pointing to the previously allocated one,
// it is deleted.
ptr.reset(new test)

此外,编译器将运算符-.解析为类似多级指针(即test*** ptr)的内容会非常混乱。按照您的逻辑,ptr.x(*ptr).x(**ptr).x(***ptr).x都是相同的。

不能将->应用于对基本类型的引用,也不能将.应用于指针,但可以将两者应用于用户定义的类型,它们将具有不同的含义。最简单的例子是智能指针,如std::shared_ptr:

struct A { int x; };
std::shared_ptr<A> p(new A);
p->x = 10;
p.reset();

是否存在通过引用选择元素和通过指针操作选择元素都有效的情况?

由于您可以在C++中重载operator->(),因此您实际上可以在同一对象上互换使用->.。你甚至可以设计一些东西,这样你就会得到不同的结果,就像这个例子:

#include <iostream>
struct Bar
{
  void hello() const { std::cout << "Bar!!!n"; }
};
struct FooBar
{
  Bar bar;
  void hello() const { std::cout << "FooBar!!!n"; }
  const Bar* operator->() const {return &bar; }
};
int main()
{
  FooBar fb;
  fb->hello();
  fb.hello();
}

当然,在真正的代码中,你永远不会做像这样疯狂的事情(尽管我在"生产"代码中见过这种事情)。

简短的答案是一个智能指针

您可以使用"."访问智能指针类参数(如果您创建自己的智能指针类,则可以从中提取当前引用计数),而您可以使用"->"运算符访问使用智能指针存储的任何内容。

最新更新