VS2010中运算符重载和LNK2019错误
我正在编写一个 Point 类,它包含三个浮点数、xyz、一些函数和重载运算符。我按以下形式对运算符进行编码:
inline Point Point::operator+ (Point point)
{
return Point(x + point.x, y + point.y, z + point.z);
}
inline void Point::operator+= (Point point)
{
x += point.x;
y += point.y;
z += point.z;
}
这是重载这些运算符的正确方法吗?我已经测试过它并且它有效,但我看到了另一种形式,如下所示:
inline Point& Point::operator+ (Point& point)
{
return Point(x + point.x, y + point.y, z + point.z);
}
inline Point& Point::operator+= (Point& point)
{
x += point.x;
y += point.y;
z += point.z;
return *this;
}
这两种形式有什么区别?
另外,我可以在 Point.cpp 文件中使用运算符,但如果我尝试在 Main.cpp 中使用它,则会收到无法解析的外部符号的 lnk2019 错误。奇怪的是,我的函数在定义文件之外工作。为了让这些运算符在它们定义的文件之外工作,我缺少什么?
I'm writing a Point class which holds three floats, x y z, some functions and overloaded operators. I coded operators in the following form:
inline Point Point::operator+ (Point point)
{
return Point(x + point.x, y + point.y, z + point.z);
}
inline void Point::operator+= (Point point)
{
x += point.x;
y += point.y;
z += point.z;
}
Is this the right way to overload these operators? I've tested it and it works but I've seen another form like so:
inline Point& Point::operator+ (Point& point)
{
return Point(x + point.x, y + point.y, z + point.z);
}
inline Point& Point::operator+= (Point& point)
{
x += point.x;
y += point.y;
z += point.z;
return *this;
}
What is the difference between the two forms?
Also I can use the operators inside my Point.cpp file but if I try to use it say in Main.cpp, I get a lnk2019 error for unresolved external symbol. Oddly, my functions work outside the defining file. What am I missing to get these operators to work outside the file they're defined in?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个运算符应该是
它不应该返回引用,因为它构造一个新对象而不是修改现有对象(一般经验法则)。 const 被添加到函数中,因为不应修改其调用点。添加对点作为参数的引用,这样就不会出现不必要的副本
第二个应该是
因为它应该修改现有点,所以它应该返回一个引用。 const 被添加到参数中,因为它不应该被更改。函数本身不是 const,因为它应该修改点本身。
您收到的链接器错误是由于内联引起的。要么在头文件中提供完整的实现,要么删除内联。
The first operator should be
it shouldn't return a reference because its excepted to construct a new object and not modify a existing one (a general rule of thumb). const is added to the function because the point its called one shouldn't be modified. a reference to the point as argument is added so there won't be unnecessary copy
The second one should be
because it supposed to modify an existing point, so it should return a reference. const is added to the argument because it shouldn't be changed. the function itself is not const because it should modify the point itself.
The linker error you get is because of the inline. either provide full implementation in header file, or remove the inline.
这是错误的,它返回一个对函数返回时不再存在的临时对象的引用。如果你足够幸运的话,这会导致段错误。如果您尝试这样做,大多数编译器都会向您发出警告。理想情况下,您可以将此运算符编写为自由函数,并根据您的成员
operator+=
实现。这几乎是首选方法,除了您应该将点作为常量引用,否则您不能将其与临时变量一起使用。返回对自身的引用是允许链接运算符的原因。人们普遍认为,当有疑问时,按照整数行事,整数就会这样做。
总结起来,“规范”的实现是:
请注意,将
operator+
设为自由函数,允许在两个操作数上发生到Point
的转换,而不仅仅是在正确的操作数上。它可以通过运算符+=方便地实现:按值获取左侧参数,以便获得可以修改的临时副本,并且通过向其添加右侧参数来实现这一点。由于operator+=
返回一个引用,我们使用这样的返回来提供将被复制为函数结果的值。That's wrong, its returning a reference to a temporary that no longer exists when the function returns. It would result in a segfault if you are lucky enough. Most compilers will give you a warning if you try to do it. Ideally you would write this operator as a free function, implemented in terms of your member
operator+=
.This is pretty much the preferred way, except that you should be taking the
point
as a const reference, otherwise you cannot use it with temporaries. Returning a reference to itself is what allows chaining operators. It's generally said that when in doubt, do as the ints, and the ints do that.Summing up, the 'cannonical' implementation would be:
Note that the having
operator+
be a free function allows conversions toPoint
to happen at both operands and not just the right one. It's conveniently implemented in terms ofoperator+=
: The left argument is taken by value in order to have a temporary copy that we can modify, and we do so by adding the right argument to it. Sinceoperator+=
returns a reference, we use such return in order to provide the value that would be copied as the function result.