C++ 在typedef结构(c+;+;)中重载运算符
我想创建一个名为C++ 在typedef结构(c+;+;)中重载运算符,c++,struct,typedef,operator-keyword,C++,Struct,Typedef,Operator Keyword,我想创建一个名为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}
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(a.x==x && a.y== y)
return true;
else
return false;
}
这是:
bool operator==(pos a) const {
if(a.x==x && a.y== y)
return true;
else
return false;
}
而不是
typedef struct{…}pos你应该做struct pos{…}代码>。这里的问题是,在定义类型名称之前,您使用的是pos
类型名称。通过将名称移动到结构定义的顶部,可以在结构定义本身中使用该名称
此外,typedef结构{…}名称代码>模式是一个C-ISM,在C++中没有太多的地方。
要回答您关于内联的问题,在这种情况下没有区别。当一个方法在结构/类定义中定义时,它被隐式地内联声明。当您显式指定inline
时,编译器实际上会忽略它,因为该方法已声明为inline
(inline
如果在多个对象文件中定义了相同的方法,则这些方法不会触发链接器错误;链接器只会忽略其中一个以外的所有方法,假设它们都是相同的实现。这是内联方法行为的唯一保证更改。现在,它们不会影响编译器的决策不确定是否内联函数;它们只是帮助使函数实现在所有转换单元中可用,这使编译器可以选择内联函数,如果它认为这样做是有益的。)
布尔运算符==(位置a)常量{-此方法不会更改对象的元素
布尔运算符==(位置a){-它可以更改对象的元素
试试这个:
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);
}
};
您的申报单及其成员的明细有点杂乱无章:
删除typedef
<> > <代码> TyPulf既不要求,也不希望C++中的类/结构声明。您的成员不知道写的代码> POS < /代码>,这是当前编译失败的核心。
更改此项:
typedef struct {....} pos;
bool operator==(pos a) const{
if(a.x==x && a.y== y)return true;
else return false;
}
为此:
struct pos { ... };
移除无关的入口线
您正在类定义本身中声明和定义成员运算符。只要实现保持在当前位置(类定义),就不需要inline
关键字
在适当的地方返回对*此
的引用
这与实现中大量的复制构造有关,如果没有强有力的理由,就不应该这样做。这与以下内容的表达思想有关:
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!)
注意:在某些情况下,为了使用复制/交换习惯用法,应该避免上述情况。尽管在这种特定情况下不需要这样做,但它可能如下所示:
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
}
您这样做是为了利用类复制器来创建一个副本,然后利用异常安全交换来执行交换。结果是传入的副本会离开(并破坏)您对象的旧内脏,而您的对象将拥有这些内脏,以及其中的优点和缺点
适当时通过常量引用传递对象
所有成员的所有输入参数当前都在复制调用时传递的任何内容。虽然这对于这样的代码来说可能微不足道,但对于较大的对象类型来说可能非常昂贵。下面给出了一个示例:
更改此项:
typedef struct {....} pos;
bool operator==(pos a) const{
if(a.x==x && a.y== y)return true;
else return false;
}
对此:(也简化了)
不复制任何内容,从而生成更高效的代码
最后,在回答您的问题时,声明为const
的成员函数或运算符与声明为非的成员函数或运算符有什么区别
const
成员声明调用该成员将不会修改基础对象(不受可变声明约束)。只能对const
对象或const
引用和指针调用const
成员函数。例如,运算符+()
不修改本地对象,因此应声明为const
。您的操作符=()
明确修改本地对象,因此操作符应不为const
摘要
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想看看赋值运算符链是如何工作的。下面演示了这一点:
a = b = c;
相当于:
b = c;
a = b;
这并不总是等同于:
a = c;
b = c;
示例代码:
#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;
}
您可能会发现这篇有关堆栈溢出的文章。您可能希望pos a
参数,而不管运算符是const pos&a
(即const引用)而不是一份pos
副本。当然,在您修复声明之后。一旦您解决了问题。您还应该在上发帖,以获取对代码其余部分的评论。您可能需要一些改进。typedef
在这里做什么?干脆放弃它。(使用struct
的typedef
的唯一原因是C兼容性,这意味着没有成员函数,没有朋友等等)我不理解这个“const Pos&other”的意思是不制作副本,并且确信您不修改