Class 数据的重载 + 运算符
Overload + Operator for Class Data
假设我有以下基本的class,我想在其中重载运算符+:
class foo {
private:
arbitrary datatype
public:
foo() { set private data; };
virtual ~foo() {};
};
我一直使用这种格式:
foo operator+( const foo &rhs );
但是,我最近偶然发现了一些人专门使用的代码:
friend foo operator+( const foo &lhs, const foo &rhs );
那么,使用一个版本而不是另一个版本是标准的吗?在某些情况下,您是否会被迫进入一个版本(这仅用于添加相同的对象类型)?我不熟悉汇编语言,但是编译器会把它们转换成相同的指令列表吗(这个问题显然取决于前两个问题的答案)?
回答您的前 2 个问题
建议(但不强制)对二元运算符使用 friend
方法,因为它允许在运算符的左侧有可转换为 class 的对象。考虑一下:
class Foo
{
// private members
public:
Foo(int) {/* ctor implementation */} // implicit convertible to int
Foo(const Foo&) { /* copy ctor implementation */ }
friend Foo operator+(const Foo& lhs, const Foo& rhs){/* implementation */}
};
现在您可以:
Foo foo1{1};
Foo foo2 = 1 + foo1; // 1 is implicitly converted to Foo here
如果operator+
是一个成员函数,上面的调用就会失败(左边,即使可以转换为Foo
,也不会被编译器自动转换),你只能使用
Foo foo2 = foo1 + 1;
因此,总而言之,对二元运算符使用 friend
使它们更 "symmetric"。
最后一题:
汇编器不会生成相同的代码,因为 friend/member operator+
做的事情略有不同。
另请参阅关于重载运算符的非常很好的指南here。
假设我有以下基本的class,我想在其中重载运算符+:
class foo {
private:
arbitrary datatype
public:
foo() { set private data; };
virtual ~foo() {};
};
我一直使用这种格式:
foo operator+( const foo &rhs );
但是,我最近偶然发现了一些人专门使用的代码:
friend foo operator+( const foo &lhs, const foo &rhs );
那么,使用一个版本而不是另一个版本是标准的吗?在某些情况下,您是否会被迫进入一个版本(这仅用于添加相同的对象类型)?我不熟悉汇编语言,但是编译器会把它们转换成相同的指令列表吗(这个问题显然取决于前两个问题的答案)?
回答您的前 2 个问题
建议(但不强制)对二元运算符使用
friend
方法,因为它允许在运算符的左侧有可转换为 class 的对象。考虑一下:class Foo { // private members public: Foo(int) {/* ctor implementation */} // implicit convertible to int Foo(const Foo&) { /* copy ctor implementation */ } friend Foo operator+(const Foo& lhs, const Foo& rhs){/* implementation */} };
现在您可以:
Foo foo1{1}; Foo foo2 = 1 + foo1; // 1 is implicitly converted to Foo here
如果
operator+
是一个成员函数,上面的调用就会失败(左边,即使可以转换为Foo
,也不会被编译器自动转换),你只能使用Foo foo2 = foo1 + 1;
因此,总而言之,对二元运算符使用
friend
使它们更 "symmetric"。最后一题:
汇编器不会生成相同的代码,因为 friend/member
operator+
做的事情略有不同。
另请参阅关于重载运算符的非常很好的指南here。