在typedef结构中重载操作符(c ++) [英] Overloading operators in typedef structs (c++)

查看:149
本文介绍了在typedef结构中重载操作符(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



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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆