typedef 结构中的重载运算符 (c++)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14047191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overloading operators in typedef structs (c++)
提问by tuket
I want to make a typedef struct called pos
(from position) that stores coordinates x and y. I am trying to overload some operators for this struct, but it does not compile.
我想创建一个名为pos
(从位置)的 typedef 结构,用于存储坐标 x 和 y。我正在尝试为此结构重载一些运算符,但它无法编译。
typedef struct {
int x;
int y;
inline pos operator=(pos a) {
x=a.x;
y=a.y;
return a;
}
inline pos operator+(pos a) {
return {a.x+x,a.y+y};
}
inline bool operator==(pos a) {
if (a.x==x && a.y== y)
return true;
else
return false;
}
} pos;
I also wanted to know the difference between this:
我也想知道这之间的区别:
inline bool operator==(pos a) {
if(a.x==x && a.y== y)
return true;
else
return false;
}
And this:
和这个:
bool operator==(pos a) const {
if(a.x==x && a.y== y)
return true;
else
return false;
}
回答by WhozCraig
The breakdown of your declaration and its members is somewhat littered:
您的声明及其成员的细分有点乱:
Remove the typedef
去除那个 typedef
The typedef
is neither required, not desired for class/struct declarations in C++. Your members have no knowledge of the declaration of pos
as-written, which is core to your current compilation failure.
在typedef
既不需要,在C不期望类/结构声明++。您的成员不知道pos
as-written的声明,这是您当前编译失败的核心。
Change this:
改变这个:
typedef struct {....} pos;
To this:
对此:
struct pos { ... };
Remove extraneous inlines
删除无关的内联
You're both declaring anddefining your member operators within the class definition itself. The inline
keyword is not needed so long as your implementations remain in their current location (the class definition)
您在类定义本身中声明和定义您的成员运算符。在inline
不需要关键字,只要您的实现仍留在当前位置(类定义)
Return references to *this
where appropriate
*this
在适当的地方返回引用
This is related to an abundance of copy-constructions within your implementation that should not be done without a strong reason for doing so. It is related to the expression ideology of the following:
这与您的实现中的大量复制结构有关,如果没有充分的理由,就不应该这样做。它与以下表达思想有关:
a = b = c;
This assigns c
to b
, and the resulting value b
is then assigned to a
. This is notequivalent to the following code, contrary to what you may think:
这将分配c
给b
,然后将结果值b
分配给a
。这不等同于以下代码,与您可能认为的相反:
a = c;
b = c;
Therefore, your assignment operator should be implemented as such:
因此,您的赋值运算符应该这样实现:
pos& operator =(const pos& a)
{
x = a.x;
y = a.y;
return *this;
}
Even here, this is not needed. The default copy-assignment operator will do the above for you free of charge (and code! woot!)
即使在这里,这也不是必需的。默认的复制赋值运算符将免费为您执行上述操作(和代码!哇!)
Note: there are times where the above should be avoided in favor of the copy/swap idiom. Though not needed for this specific case, it may look like this:
注意:有时为了支持复制/交换习语而应避免上述情况。尽管对于这种特定情况不需要,但它可能如下所示:
pos& operator=(pos a) // by-value param invokes class copy-ctor
{
this->swap(a);
return *this;
}
Then a swap method is implemented:
然后实现了一个交换方法:
void pos::swap(pos& obj)
{
// TODO: swap object guts with obj
}
You do this to utilize the class copy-ctor to make a copy, then utilize exception-safe swapping to perform the exchange. The result is the incoming copy departs (and destroys) your object's old guts, while your object assumes ownership of there's. Read more the copy/swap idiom here, along with the pros and cons therein.
您这样做是为了利用类 copy-ctor 进行复制,然后利用异常安全交换来执行交换。结果是传入的副本离开(并销毁)您对象的旧胆量,而您的对象则承担了那里的所有权。在此处阅读更多复制/交换习语,以及其中的优缺点。
Pass objects by const reference when appropriate
适当时通过常量引用传递对象
All of your input parameters to all of your members are currently making copies of whatever is being passed at invoke. While it may be trivial for code like this, it can be veryexpensive for larger object types. An exampleis given here:
您所有成员的所有输入参数当前都在复制在调用时传递的任何内容。虽然对于这样的代码来说可能是微不足道的,但对于较大的对象类型来说可能非常昂贵。这里给出了一个例子:
Change this:
改变这个:
bool operator==(pos a) const{
if(a.x==x && a.y== y)return true;
else return false;
}
To this: (also simplified)
为此:(也简化)
bool operator==(const pos& a) const
{
return (x == a.x && y == a.y);
}
No copies of anythingare made, resulting in more efficient code.
没有复制任何东西,从而产生更高效的代码。
Finally, in answering your question, what is the difference between a member function or operator declared as const
and one that is not?
最后,在回答您的问题时,声明为的成员函数或运算符与声明const
为非的成员函数或运算符之间有什么区别?
A const
member declares that invoking that member will notmodifying the underlying object (mutable declarations not withstanding). Only const
member functions can be invoked against const
objects, or const
references and pointers. For example, your operator +()
does not modify your local object and thus should be declared as const
. Your operator =()
clearly modifies the local object, and therefore the operator should notbe const
.
甲const
构件声明调用该成员将不修改底层对象(可变声明不耐受)。只能const
针对const
对象或const
引用和指针调用成员函数。例如,您operator +()
不会修改您的本地对象,因此应声明为const
. 你operator =()
清楚地修改了本地对象,因此,运营商应该不会是const
。
Summary
概括
struct pos
{
int x;
int y;
// default + parameterized constructor
pos(int x=0, int y=0)
: x(x), y(y)
{
}
// assignment operator modifies object, therefore non-const
pos& operator=(const pos& a)
{
x=a.x;
y=a.y;
return *this;
}
// addop. doesn't modify object. therefore const.
pos operator+(const pos& a) const
{
return pos(a.x+x, a.y+y);
}
// equality comparison. doesn't modify object. therefore const.
bool operator==(const pos& a) const
{
return (x == a.x && y == a.y);
}
};
EDITOP wanted to see how an assignment operator chain works. The following demonstrates how this:
编辑OP 想看看赋值运算符链是如何工作的。下面演示了如何做到这一点:
a = b = c;
Is equivalent to this:
相当于:
b = c;
a = b;
And that this does not always equate to this:
这并不总是等同于:
a = c;
b = c;
Sample code:
示例代码:
#include <iostream>
#include <string>
using namespace std;
struct obj
{
std::string name;
int value;
obj(const std::string& name, int value)
: name(name), value(value)
{
}
obj& operator =(const obj& o)
{
cout << name << " = " << o.name << endl;
value = (o.value+1); // note: our value is one more than the rhs.
return *this;
}
};
int main(int argc, char *argv[])
{
obj a("a", 1), b("b", 2), c("c", 3);
a = b = c;
cout << "a.value = " << a.value << endl;
cout << "b.value = " << b.value << endl;
cout << "c.value = " << c.value << endl;
a = c;
b = c;
cout << "a.value = " << a.value << endl;
cout << "b.value = " << b.value << endl;
cout << "c.value = " << c.value << endl;
return 0;
}
Output
输出
b = c
a = b
a.value = 5
b.value = 4
c.value = 3
a = c
b = c
a.value = 4
b.value = 4
c.value = 3
回答by cdhowie
Instead of typedef struct { ... } pos;
you should be doing struct pos { ... };
. The issue here is that you are using the pos
type name before it is defined. By moving the name to the top of the struct definition, you are able to use that name within the struct definition itself.
而不是typedef struct { ... } pos;
你应该做的struct pos { ... };
。这里的问题是您pos
在定义之前使用了类型名称。通过将名称移到结构定义的顶部,您可以在结构定义本身中使用该名称。
Further, the typedef struct { ... } name;
pattern is a C-ism, and doesn't have much place in C++.
此外,该typedef struct { ... } name;
模式是 C-ism,在 C++ 中没有太多位置。
To answer your question about inline
, there is no difference in this case. When a method is defined within the struct/class definition, it is implicitlydeclared inline. When you explicitly specify inline
, the compiler effectively ignores it because the method is already declared inline.
要回答您关于 的问题inline
,在这种情况下没有区别。当在结构/类定义中定义方法时,它被隐式声明为内联。当您显式指定 时inline
,编译器会有效地忽略它,因为该方法已声明为内联。
(inline
methods will not trigger a linker error if the same method is defined in multiple object files; the linker will simply ignore all but one of them, assuming that they are all the same implementation. This is the only guaranteed change in behavior with inline methods. Nowadays, they do not affect the compiler's decision regarding whether or not to inline functions; they simply facilitate making the function implementation available in all translation units, which gives the compiler the optionto inline the function, if it decides it would be beneficial to do so.)
(inline
如果在多个目标文件中定义了相同的方法,则方法不会触发链接器错误;链接器将简单地忽略除其中一个之外的所有方法,假设它们都是相同的实现。这是使用内联方法唯一有保证的行为变化. 如今,它们不影响编译器关于是否内联函数的决定;它们只是促进使函数实现在所有翻译单元中可用,这使编译器可以选择内联函数,如果它决定将有益于这样做。)
回答by maskotky
- bool operator==(pos a) const{ - this method doesn't change object's elements.
- bool operator==(pos a) { - it may change object's elements.
- bool operator==(pos a) const{ - 此方法不会更改对象的元素。
- bool operator==(pos a) { - 它可能会改变对象的元素。
回答by Krozark
try this:
尝试这个:
struct Pos{
int x;
int y;
inline Pos& operator=(const Pos& other){
x=other.x;
y=other.y;
return *this;
}
inline Pos operator+(const Pos& other) const {
Pos res {x+other.x,y+other.y};
return res;
}
const inline bool operator==(const Pos& other) const {
return (x==other.x and y == other.y);
}
};