重载函数既不按值也不按引用获取对象,而是获取指向对象的取消引用指针
Overloaded functions neither take objects by value, nor by reference, but take de-referenced pointer to object
预先说明:问题涉及我自己实现的一个vector-class,与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) {
//...
}
它引用两个向量,returns它们的和。
现在,当我尝试以下操作时:
Vector foo();
Vector bar();
Vector byVal = foo + bar; //using objects
Vector byRef = &foo + &bar; //using address
在这两种情况下,我的 IDE 告诉我以下内容:
expression must have integral or unscoped enum-type
在第二种情况下这是有道理的,因为我只会在被调用函数采用指针时传递一个 yield 指针,对于采用引用的函数,我可以传递对象本身,但我不不明白为什么 在这里不能只使用对象。
让我更困惑的是,以下 似乎是可能的:
Vector* foo = new Vector();
Vector* bar = new Vector();
Vector foobar = *foo + *bar;
也就是说,我可以将 取消引用的指针 与重载运算符一起使用。
这种行为的原因是什么,在这种情况下我应该如何使用我的重载运算符?
Vector foo();
Vector bar();
这些不是变量声明。这些是函数声明。它们是 return Vector
并采用空参数列表的函数。
鉴于不能将函数相加,也不能将函数指针相加,foo + bar
和&foo + &bar
都是ill-formed。
为了value-initialise一个变量,你可以使用以下任一方法:
Vector foo{}; // uniform initialsation
auto bar = Vector(); // copy initialisation syntax
I wanted to call the constructor of Vector, that doesn't take any arguments
确实如此。没有参数的函数声明和带有空初始化列表的变量声明是不明确的。这是由一条语言规则解决的,该规则规定如果一段代码在语法上可以是函数声明或其他东西,那么它就是一个函数声明。
如果函数将参数标记为 &
,则作为参数传递的对象将通过引用传递。对象的地址是隐式,所以你不必(实际上不能)在要传递的参数对象之前写一个&
。
进一步注意 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;
预先说明:问题涉及我自己实现的一个vector-class,与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) {
//...
}
它引用两个向量,returns它们的和。 现在,当我尝试以下操作时:
Vector foo();
Vector bar();
Vector byVal = foo + bar; //using objects
Vector byRef = &foo + &bar; //using address
在这两种情况下,我的 IDE 告诉我以下内容:
expression must have integral or unscoped enum-type
在第二种情况下这是有道理的,因为我只会在被调用函数采用指针时传递一个 yield 指针,对于采用引用的函数,我可以传递对象本身,但我不不明白为什么 在这里不能只使用对象。
让我更困惑的是,以下 似乎是可能的:
Vector* foo = new Vector();
Vector* bar = new Vector();
Vector foobar = *foo + *bar;
也就是说,我可以将 取消引用的指针 与重载运算符一起使用。
这种行为的原因是什么,在这种情况下我应该如何使用我的重载运算符?
Vector foo(); Vector bar();
这些不是变量声明。这些是函数声明。它们是 return Vector
并采用空参数列表的函数。
鉴于不能将函数相加,也不能将函数指针相加,foo + bar
和&foo + &bar
都是ill-formed。
为了value-initialise一个变量,你可以使用以下任一方法:
Vector foo{}; // uniform initialsation
auto bar = Vector(); // copy initialisation syntax
I wanted to call the constructor of Vector, that doesn't take any arguments
确实如此。没有参数的函数声明和带有空初始化列表的变量声明是不明确的。这是由一条语言规则解决的,该规则规定如果一段代码在语法上可以是函数声明或其他东西,那么它就是一个函数声明。
如果函数将参数标记为 &
,则作为参数传递的对象将通过引用传递。对象的地址是隐式,所以你不必(实际上不能)在要传递的参数对象之前写一个&
。
进一步注意 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;