- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
注意:答案按特定顺序给出,但由于许多用户根据投票而不是给出时间对答案进行排序,这里是 答案索引按照它们最有意义的顺序:
最佳答案
常用运算符重载
重载运算符的大部分工作是样板代码。这并不奇怪,因为操作符只是语法糖,它们的实际工作可以由(并且经常被转发到)普通函数来完成。但重要的是你要正确地获得这个样板代码。如果你失败了,要么你的运算符(operator)的代码不能编译,要么你的用户的代码不能编译,要么你的用户的代码表现得令人惊讶。
赋值运算符
关于分配有很多话要说。然而,大部分内容已经在GMan's famous Copy-And-Swap FAQ中说到了。 ,所以我会在这里跳过大部分内容,只列出完美的赋值运算符以供引用:
X& X::operator=(X rhs)
{
swap(rhs);
return *this;
}
<<
和
>>
,虽然仍然用于硬件接口(interface)以实现它们从 C 继承的位操作函数,但在大多数应用程序中作为重载的流输入和输出运算符变得更加普遍。有关作为位操作运算符重载的指导,请参阅下面有关二进制算术运算符的部分。当您的对象与 iostreams 一起使用时,要实现您自己的自定义格式和解析逻辑,请继续。
std::ostream& operator<<(std::ostream& os, const T& obj)
{
// write obj to stream
return os;
}
std::istream& operator>>(std::istream& is, T& obj)
{
// read obj from stream
if( /* no valid object of T found in stream */ )
is.setstate(std::ios::failbit);
return is;
}
operator>>
,只有在读取本身成功时才需要手动设置流的状态,但结果不是预期的。
this
成员函数的参数。除此之外,它可以被重载以接受任意数量的附加参数,包括零。
class foo {
public:
// Overloaded call operator
int operator()(const std::string& y) {
// ...
}
};
foo f;
int a = f("hello");
!
应该(根据相同的规则)作为成员函数来实现。 (但重载通常不是一个好主意。)
std::sort()
)和类型(例如
std::map
)将始终只期望
operator<
在场。但是,您类型的用户也希望所有其他运算符都存在,因此如果您定义
operator<
,请务必遵循运算符重载的第三条基本规则,并定义所有其他 bool 比较运算符。实现它们的规范方法是这样的:
inline bool operator==(const X& lhs, const X& rhs){ /* do actual comparison */ }
inline bool operator!=(const X& lhs, const X& rhs){return !operator==(lhs,rhs);}
inline bool operator< (const X& lhs, const X& rhs){ /* do actual comparison */ }
inline bool operator> (const X& lhs, const X& rhs){return operator< (rhs,lhs);}
inline bool operator<=(const X& lhs, const X& rhs){return !operator> (lhs,rhs);}
inline bool operator>=(const X& lhs, const X& rhs){return !operator< (lhs,rhs);}
||
、
&&
)的语法遵循比较运算符的规则。但是,您不太可能为这些 2 找到合理的用例。
*this
, 需要是
const
, 也。因此,作为成员函数实现的比较运算符必须具有以下签名:
bool operator<(const X& rhs) const { /* do actual comparison with *this */ }
const
。)
||
的内置版本和
&&
使用快捷语义。而用户定义的(因为它们是方法调用的语法糖)不使用快捷语义。用户会期望这些操作符具有快捷语义,并且他们的代码可能依赖于它,因此强烈建议永远不要定义它们。
class X {
X& operator++()
{
// do actual increment
return *this;
}
X operator++(int)
{
X tmp(*this);
operator++();
return tmp;
}
};
i++
,很难记住做
++i
相反,当
i
不是内置类型(而且在更改类型时您必须更改代码),因此最好养成始终使用前缀增量的习惯,除非明确需要后缀。
+
,还提供
+=
, 如果您提供
-
, 不要省略
-=
等。据说 Andrew Koenig 是第一个观察到复合赋值运算符可以用作非复合运算符的基础的人。即运算符
+
根据
+=
实现,
-
根据
-=
实现等等。
+
和它的同伴应该是非成员,而它们的复合赋值对应物(
+=
等),改变它们的左参数,应该是成员。这是
+=
的示例代码和
+
;其他二元算术运算符应该以相同的方式实现:
class X {
X& operator+=(const X& rhs)
{
// actual addition of rhs to *this
return *this;
}
};
inline X operator+(X lhs, const X& rhs)
{
lhs += rhs;
return lhs;
}
operator+=
每个引用返回其结果,而
operator+
返回其结果的拷贝。当然,返回引用通常比返回拷贝更有效,但在
operator+
的情况下,没有办法绕过复制。当你写
a + b
,您希望结果是一个新值,这就是为什么
operator+
必须返回一个新值。 3
operator+
取其左操作数
通过复制 而不是通过常量引用。其原因与
operator=
的原因相同。每个拷贝取其参数。
~
&
|
^
<<
>>
应该以与算术运算符相同的方式实现。但是,(除了用于输出和输入的重载
<<
和
>>
),重载这些的合理用例很少。
a += b
一般来说,比
a + b
更有效如果可能,应该首选。
class X {
value_type& operator[](index_type idx);
const value_type& operator[](index_type idx) const;
// ...
};
operator[]
返回的数据元素| (在这种情况下,您可以省略非常量变体),您应该始终提供运算符的两个变体。
class X {
value_type& operator[](index_type idx);
value_type operator[](index_type idx) const;
// ...
};
*
和二进制中缀指针成员访问运算符
->
:
class my_ptr {
value_type& operator*();
const value_type& operator*() const;
value_type* operator->();
const value_type* operator->() const;
};
->
运算符,如果
value_type
是
class
(或
struct
或
union
)类型,另一个
operator->()
被递归调用,直到
operator->()
返回一个非类类型的值。
operator->*()
见
this question .它很少使用,因此很少重载。事实上,即使是迭代器也不会重载它。
关于c++ - 运算符重载的基本规则和习惯用法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4421706/
Or 运算符 对两个表达式进行逻辑“或”运算。 result = expression1 Or expression2 参数 result 任意数值变量。 expression1 任意
Not 运算符 对表达式执行逻辑非运算。 result = Not expression 参数 result 任意数值变量。 expression 任意表达式。 说明 下表显示如何
Is 运算符 比较两个对象引用变量。 result = object1 Is object2 参数 result 任意数值变量。 object1 任意对象名。 object2 任意
\ 运算符 两个数相除并返回以整数形式表示的结果。 result = number1\number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
And 运算符 对两个表达式进行逻辑“与”运算。 result = expression1 And expression2 参数 result 任意数值变量。 expression1
运算符(+) 计算两个数之和。 result = expression1 + expression2 参数 result 任意数值变量。 expression1 任意表达式。 exp
我对此感到困惑snippet : var n1 = 5-"4"; var n2 = 5+"4"; alert(n1); alert(n2); 我知道 n1 是 1。那是因为减号运算符会将字符串“4”转
我想我会得到 12,而不是 7。 w++,那么w就是4,也就是100,而w++, w 将是 8,1000;所以 w++|z++ 将是 100|1000 = 1100 将是 12。 我怎么了? int
Xor 运算符 对两个表达式进行逻辑“异或”运算。 result = expression1 Xor expression2 参数 result 任意数值变量。 expression1
Mod 运算符 两个数值相除并返回其余数。 result = number1 Mod number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
Imp 运算符 对两个表达式进行逻辑蕴涵运算。 result = expression1 Imp expression2 参数 result 任意数值变量。 expression1 任
Eqv 运算符 执行两个表达式的逻辑等价运算。 result = expression1 Eqv expression2 参数 result 任意数值变量。 expression1 任
我有一个运算符重载的简单数学 vector 类。我想为我的运算符(operator)获取一些计时结果。我可以通过计时以下代码轻松计时我的 +=、-=、*= 和/=: Vector sum; for(s
我是用户定义比较运算符的新手。我正在读一本书,其中提到了以下示例: struct P { int x, y; bool operator、运算符<等),我们
在 SQL 的维基百科页面上,有一些关于 SQL 中 bool 逻辑的真值表。 [1] 维基百科页面似乎来源于 SQL:2003 标准。 等号运算符 (=) 的真值表与 SQL:2003 草案中的 I
我遇到了一个奇怪的 C++ 运算符。 http://www.terralib.org/html/v410/classoracle_1_1occi_1_1_number.html#a0f2780081f
我正在阅读关于 SO 和 answers 中的一个问题,它被提到为: If no unambiguous matching deallocation function can be found, pr
我偶然发现了这个解决方案,但我无法理解其中到底发生了什么。谁能解释一下! 据我了解,它试图通过计算一半的单元格然后将其加倍来计算 a*b 网格中的单元格数量。但是我无法理解递归调用。 请不要建议其他解
Go的基本类型 布尔类型bool 长度:1字节 取值:布尔类型的取值只能是true或者false,不能用数字来表示 整型 通用整型 int / uint(有符号 / 无符号,下面也类似) 长度:根据运
在本教程中,您将学习JavaScript中可用的不同运算符,以及在示例的帮助下如何使用它们。 什么是运算符? 在JavaScript中,运算符是一种特殊符号,用于对运算数(值和变量)执行操作。例如,
我是一名优秀的程序员,十分优秀!