在typedef结构中重载操作符(c ++) [英] Overloading operators in typedef structs (c++)
问题描述
我想创建一个名为 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;
我也想知道这之间的区别:
inline bool operator ==(pos a){
if(ax == x& ay == y)
return true;
else
return false;
}
而且:
bool operator ==(pos a)const {
if(ax == x& ay == y)
return true;
else
return false;
}
其成员有点乱七八糟:
删除 typedef
$ b
typedef
既不是必需的,对于C / C ++中的类/ struct声明是不需要的。您的成员不知道如何声明 pos
原样,这是您当前编译失败的核心。
更改:
typedef struct {....} pos;
到此:
struct pos {...};
删除无关的内联
您同时声明和在类定义中定义成员运算符。
inline
关键字不需要,只要您的实现保持在其当前位置(类定义)
p>这与您的实现中的大量拷贝构造相关,如果没有这样做的强烈理由,就不应该这样做。它与以下的表达意识形态有关:
a = b = c;
这会将
c
指派给b
,然后将结果值b
分配给a
。这是不等同于以下代码,与您可能认为的相反:a = c ;
b = c;
因此,您的赋值运算符应该实现:
pos& operator =(const pos& a)
{
x = a.x;
y = a.y;
return * this;
}
即使在这里,也不需要。默认的副本赋值运算符将为您免费完成上述操作(和代码!woot!)
strong>:有时候应该避免使用复制/交换惯用语。虽然这个特定情况不需要,它可能看起来像这样:
pos& operator =(pos a)// by-value param invokes class copy-ctor
{
this-> swap(a);
return * this;
}
然后执行交换方法:
void pos :: swap(pos& obj)
{
// TODO:swap object guts with obj
}
您可以使用类copy-ctor进行复制,然后利用异常安全交换执行找的零钱。结果是传入的副本离开(和销毁)你的对象的旧勇气,而你的对象假设的所有权。 阅读更多此处的复制/交换惯用语,以及其中的优点和缺点。
在适当时通过const引用传递对象
参数给你的所有成员目前正在复制的任何正在传递的调用。虽然对于像这样的代码可能是微不足道的,但对于较大的对象类型,它可能非常昂贵。示例如下:
更改:
bool operator = =(pos a)const {
if(ax == x& ay == y)return true;
else return false;
}
b $ b
bool operator ==(const pos& a)const
{
return(x == ax& y == ay) ;
}
没有任何副本更高效的代码。
最后,在回答您的问题时,成员函数或运算符之间的区别是: code> const 和一个不是?
A
const
成员声明调用该成员将不会修改底层对象可变声明不承认)。只有const
成员函数可以针对const
对象或const
引用和指针。例如,operator +()
不会修改您的本地对象,因此应该声明为const
。您的operator =()
清楚地修改本地对象,因此运算符不应为const $ c $
pre>struct pos
{
int x;
int y;
//默认+参数化构造函数
pos(int x = 0,int y = 0)
:x(x),y(y)
{
}
//赋值运算符修改对象,因此非const
pos& operator =(const pos& a)
{
x = a.x;
y = a.y;
return * this;
}
// addop。不修改对象。因此const。
pos operator +(const pos& a)const
{
return pos(a.x + x,a.y + y);
}
//等比较。不修改对象。因此const。
bool operator ==(const pos& a)const
{
return(x == a.x& y == a.y);
}
};
EDIT 以了解赋值运算符链如何工作。以下演示如何:
a = b = c;
等效于:
b = c;
a = b;
这并不总是等于:
a = c;
b = c;
示例代码:
$ b b
#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)
{
}
b $ b obj& operator =(const obj& o)
{
cout<名称<< =<< o.name<< endl;
value =(o.value + 1); //注意:我们的值比rhs多一个。
return * this;
}
};
int main(int argc,char * argv [])
{
obj a(a,1),b ),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;
}
输出
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
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.
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;
}
The breakdown of your declaration and its members is somewhat littered:
Remove the 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.
Change this:
typedef struct {....} pos;
To this:
struct pos { ... };
Remove extraneous inlines
You're both declaring and defining 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)
Return references to *this
where appropriate
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 not equivalent to the following code, contrary to what you may think:
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.
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 very expensive 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 anything are 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?
A const
member declares that invoking that member will not modifying 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 not be 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);
}
};
EDIT OP wanted to see how an assignment operator chain works. The following demonstrates how this:
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
这篇关于在typedef结构中重载操作符(c ++)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!