在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(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
typedef
既不需要,也不需要C 中的类/结构声明。您的成员不了解pos
撰写的声明,这是您当前汇编失败的核心。
更改此内容:
typedef struct {....} pos;
:
struct pos { ... };
删除外部嵌入式
您既声明 and 在类定义本身中定义您的会员运营商。只要您的实现保留在其当前位置(类定义)
,就不需要inline
关键字。在适当的情况下返回*this
的引用
这与实施中的大量拷贝构建有关,如果没有强有力的理由,就不应这样做。它与以下的表达意识形态有关:
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!)
Note :有时应避免以上内容以 coppy/swap indiom 。尽管这种特定情况不需要,但看起来像这样:
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制作副本,然后利用异常安全交换来执行交换。结果是传入的副本离开(并摧毁)您的对象的旧胆量,而您的对象则假定存在。在此处阅读更多副本/交换成语以及其中的利弊。
在适当的时候通过cont参考传递对象
您所有成员的所有输入参数当前正在签署Invoke中通过的任何内容。尽管对于这样的代码来说可能是微不足道的,但对于较大的对象类型来说,它可能非常昂贵。这里给出的一个例子:
更改此内容:
bool operator==(pos a) const{
if(a.x==x && a.y== y)return true;
else return false;
}
对此:(也简化)
bool operator==(const pos& a) const
{
return (x == a.x && y == a.y);
}
没有任何副本,从而产生了更有效的代码。
最后,在回答您的问题时,将成员函数或运算符声明为const
,而不是一个?
const
成员声明,调用该成员将修改基本对象(不承受的可变声明)。只能针对const
对象或const
引用和指针调用const
成员函数。例如,您的operator +()
不会修改您的本地对象,因此应将其声明为const
。您的operator =()
明确修改了本地对象,因此操作员应不是是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);
}
};
编辑 OP希望查看分配操作员链的工作原理。以下说明了这一点:
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;
}
输出
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 struct { ... } pos;
您应该做struct pos { ... };
。这里的问题是您在定义pos
类型名称之前使用。通过将名称移至struct定义的顶部,您可以在struct定义本身中使用该名称。
此外,typedef struct { ... } name;
模式是C-主义,在C 中没有太多位置。
要回答有关inline
的问题,这种情况没有区别。当在结构/类定义中定义方法时,它是隐式内联声明的。当您明确指定inline
时,编译器有效地忽略了它,因为该方法已经被串联声明。
(如果在多个对象文件中定义了相同的方法,则inline
方法不会触发链接器错误;假设它们都是相同的实现。链接器将简单地忽略所有方法。使用内联方法的行为。如今,它们不会影响编译器关于是否要在内联函数的决定;它们只是促进使所有翻译单元中可用的函数实现,这使编译器允许编译器 option inline该功能,如果决定这样做将是有益的。)
尝试以下:
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);
}
};
- bool operator ==(pos a)const { - 此方法不会更改对象的元素。
- bool operator ==(pos a){ - 它可能会更改对象的元素。
- 如何在音频处理中使用超能力时间拉伸类
- 我的超类中的模板问题与结构定义
- 在具有 MPI 的超立方体中广播
- 在 c++ 中调用超构造函数之前做一些事情
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- C++为API中定义的结构创建超类
- 确保指向超类的指针指向c++中某个子类的对象
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- C++:从类型索引中获取超类类型索引
- C++11 中对超载'ref(Select::Expressions::Code&)'的调用模棱两可
- 如何将项目放入具有模板化超类类型的向量中
- QT 中的串行通信超时与 Arduino
- 是否有一种方法可以在超载运算符函数中接触默认运算符函数
- 如何将基类方法超载作为参数传递到C 中的模板类
- 班级(Arduino)中的超载方法
- 在C 中的超载运算符中使用局部变量
- 尝试在构造函数中超限时间
- 多态性(C )的派生类中的超载函数
- 更改所有子类中超类变量的值
- 如何在C++中超类某些数据结构