【问题标题】:Overloaded functions neither take objects by value, nor by reference, but take de-referenced pointer to object重载函数既不通过值获取对象,也不通过引用获取对象,而是获取指向对象的解引用指针
【发布时间】:2019-11-09 18:23:03
【问题描述】:

提前说明:问题与我自己实现的vector类有关,与std::vector无关

考虑以下运算符重载:

//in the Vector-class(declaration)
friend Vector operator+(const Vector& a, const Vector& b);

//outside the Vector-class(implementation)
Vector operator+(const Vector& a, const Vector&b) {
//...
}

引用两个向量,并返回它们的总和。 现在,当我尝试以下操作时:

Vector foo();
Vector bar();

Vector byVal = foo + bar; //using objects
Vector byRef = &foo + &bar; //using address

在这两种情况下,我的 IDE 都会告诉我以下信息:

表达式必须具有整数或无范围枚举类型

在第二种情况下,这是有道理的,因为我只会在被调用函数接受指针时传递一个产生的指针,而对于一个接受引用的函数,我可以传递对象本身,但我不明白为什么这里不能只使用对象。

让我更困惑的是,以下似乎是可能的:

Vector* foo = new Vector();
Vector* bar = new Vector();

Vector foobar = *foo + *bar;

也就是说,我可以将 de-referenced pointers 与重载运算符一起使用。

这种行为的原因是什么,在这种情况下我应该如何使用我的重载运算符?

【问题讨论】:

  • Vector byRef = &foo + &bar; //by reference 这将传递foobar 的地址来调用操作符函数。您似乎对参考参数的工作方式有一些严重的误解。
  • 答案已经解决了您的问题。但是,我仍然想向您推荐以下视频,以了解如何将值传递给函数:youtube.com/watch?v=PNRju6_yn3o
  • @πάνταῥεῖ 我认为我的问题更多在于“通过引用传递”与“通过值传递”的定义,这篇文章stackoverflow.com/questions/410593/pass-by-reference-value-in-c 帮助我更清楚地了解了这一点。我编辑了我的问题,希望我的陈述现在更正确。
  • @ancientchild 我可能应该把你的问题作为你链接的那个人的骗子来结束,是的。

标签: c++ reference operator-overloading operators dereference


【解决方案1】:
Vector foo();
Vector bar();

这些不是变量声明。这些是函数声明。它们是返回 Vector 并采用空参数列表的函数。

鉴于不能一起添加函数,也不能一起添加函数指针,foo + bar&foo + &bar 都是非良构的。

为了对变量进行值初始化,您可以使用以下任一方法:

Vector foo{};        // uniform initialsation
auto bar = Vector(); // copy initialisation syntax

我想调用 Vector 的构造函数,它不带任何参数

确实如此。没有参数的函数声明和具有空初始化列表的变量声明是不明确的。这是由一条语言规则解决的,即如果一段代码在语法上可以是函数声明或其他内容,那么它就是函数声明。

【讨论】:

  • 哦,我明白了,谢谢!我想调用 Vector 的构造函数,它不带任何参数,就像我习惯调用带参数的构造函数一样,但我声明了两个返回 Vector 的函数。
【解决方案2】:

如果函数将参数标记为&,则作为参数传递的对象将通过引用传递。对象的地址是隐式获取的,因此您不必(实际上绝不能)在要传递的参数对象之前写&

进一步注意Vector foo(); 声明的是一个函数,而不是一个对象。这就是您的编译器抱怨您的两个调用的原因。

Vector operator+(const Vector& a, const Vector&b) {
//...
}

Vector foo;
Vector bar;

Vector byVal = foo + bar; //by reference because parameter in operator + is marked as "call by reference" 
// Wrong: Vector byRef = &foo + &bar; 

【讨论】:

  • 请注意,OP 似乎尝试了值初始化。 Vector foo; 不是值初始化,而是默认初始化。如果Vector 是可简单构造的,情况就不同了。
猜你喜欢
  • 1970-01-01
  • 2014-06-11
  • 2023-03-16
  • 2019-10-21
  • 1970-01-01
  • 2021-02-21
  • 1970-01-01
  • 2020-01-18
相关资源
最近更新 更多