【发布时间】:2011-06-10 01:05:25
【问题描述】:
我可以使用一些帮助来理解 C++ 中的以下内容,尤其是运算符和函数之间的区别:
- 什么是运算符?
- 什么是函数?
- 它们之间有什么区别?
- 用户定义的
operator+()是函数还是运算符? - 运算符可以在编译时对操作数进行操作吗?它们总是在编译时运行吗? (如 C++ 中的
sizeof())
【问题讨论】:
标签: c++ operators user-defined-functions
我可以使用一些帮助来理解 C++ 中的以下内容,尤其是运算符和函数之间的区别:
operator+()是函数还是运算符?sizeof())【问题讨论】:
标签: c++ operators user-defined-functions
在 C++ 中,您可以覆盖符号 +、-、== 等应用于类实例时的作用。通过在 A 类中定义“operator+”方法,您可以告诉编译器如何处理如下代码:
A a, b, c;
c = a + b; // the + here actually calls a.operator+(b)
它也是一个函数,或者更准确地说是一个实例方法,在某种意义上它是被调用的东西。
编辑:另见http://en.wikipedia.org/wiki/Operator_overloading 和http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading
【讨论】:
运算符和函数之间没有任何意义的区别,只是运算符的语法不同。然而,原始运算符不是函数。
【讨论】:
函数和运算符之间没有太大的区别。您可以将 using 运算符(例如 'a+b')视为函数 operator+(a,b) 的快捷方式,该函数是为 a 和 b 的类型定义的。当然,原始类型(如整数)的运算符和其他一些例外情况不一定要这样定义。
因此,回答您的一些具体问题:
自定义operator+()是函数还是运算符?
实现运算符的函数。
运算符可以在编译时对操作数进行操作吗?它们总是在编译时运行吗?
由于它是一个函数,它在运行时运行,但在某些情况下,编译器优化可以在编译时对某些运算符起作用。我不是 100% 确定你为什么要问这个,所以也许这里有一些我不知道的东西。
【讨论】:
什么是运算符?
operator 通常是对给定某种形式的标点符号的变量执行的操作。例如,operator+ 在两个整数之间的默认行为是将它们相加。
什么是函数?
function 是一个子例程——一个可重用的代码块。
它们有什么区别?
就用户代码而言,除了语法之外,什么都没有。请注意,如果您覆盖 operator||、operator&& 或(在较小程度上)operator,,则会更改内置运算符语义的语义。在&& 和|| 的情况下,您将通常短路的操作变成不是短路的操作。在逗号的情况下,您需要确保从左到右评估参数,因为逗号运算符通常以这种方式运行。
用户自定义operator+()是函数还是运算符?
两者都没有。它是用户定义的运算符重载。函数名不能以关键字operator 开头,运算符只是用于调用运算符重载的实际标点符号,即+ 或-。 编辑:请注意,虽然从技术上讲它不是一个函数,但它确实具有函数调用的语义,如 @Martin York's excellent answer 所示。
运算符可以在编译时对操作数进行操作吗?它们总是在编译时运行吗? (类似于 C++ 中的 sizeof())
不,sizeof 不能重载。如果你想完成某种形式的编译时操作,你需要使用template metaprogramming 之类的东西。请注意,如果编译器能够在编译时进行计算,它当然可能会忽略对重载运算符的调用。
【讨论】:
Is user-defined operator+() a function or operator?。用户类的重载运算符是一个函数/方法。运算符的使用只是函数/方法调用的语法糖。 a+b 实际上是:a.operator+(b)。 operator+ 方法的行为与类中的任何其他方法相同,您甚至可以像使用任何其他方法(如 add())一样获取其地址。
std::mem_fun_ref 调用运算符重载。
函数和运算符之间只有两个细微差别。
x+y 或operator+(a,b))。operator== 必须恰好有两个参数)。此规则的例外是函数调用 operator(),它可以使用任意数量的任意参数进行重载。【讨论】:
什么是运算符?
运算符是在表达式中使用的符号。
例如:+ - * / 等
在内置类型上,操作定义明确且不可更改。
对于用户定义的类型,运算符可以定义为函数/方法调用的语法糖
Array a;
a = b + c; // a.operator=(b.operator+(c));
什么是函数?
我们大部分时间都可以互换使用术语功能/方法。唯一的区别是方法与类对象的实例相关联。否则它们是相同的。它们提供了一种将一组指令组合在一起的方法。
它们有什么区别?
运算符对内置类型的操作由编译器定义。
运算符对用户定义类型的操作是函数调用。
自定义运算符+()是函数还是运算符?
它是一个函数(或方法)。在用户定义类型上使用运算符是函数调用的语法糖。尽管在正常对话中,他们仍被称为操作员。
运算符可以在编译时对操作数进行操作吗?
对于内置类型是的。编译器具有广泛的优化使用的能力。
对于用户定义的类型。它可以像其他可能导致被淘汰的函数一样对算子进行优化,但代码不会在编译时执行。
它们总是在编译时运行吗? (类似于 C++ 中的 sizeof())
没有。 sizeof() 比较独特。
为了展示用户定义类中的操作符的行为就像函数一样,这里是一个使用 mem_fun_ref 的示例
#include <vector>
#include <algorithm>
#include <memory>
#include <functional>
class X
{
public:
// Non standard operators.
// Because std::mem_fun_ref has a known weakness in that it can
// not be used with methods that take parameters be reference.
//
// The principle is the same though. That the operator+ can be
// used anywhere that the add() method can be used.
X& operator+(X* rhs) { return *this;}
X& add(X* rhs) { return *this;}
};
typedef X& (X::*MEMF)(X* rhs);
int main()
{
MEMF p1 = &X::add;
MEMF p2 = &X::operator+;
X value;
std::vector<X> data;
std::for_each(data.begin(),
data.end(),
std::bind2nd(std::mem_fun_ref(&X::operator+),&value));
}
【讨论】:
运算符 是一个符号,如+、-、+= 等等(参见 13.5)。它们没有任何意义。在语义分析期间,确定运算符的含义。
函数是构造函数、析构函数、转换函数(看起来像operator type())或运算符函数(函数模板专门化和实例化可以依次产生这些)。
运算符函数是实现运算符的东西(见13.5)。一个例子是operator+。这些在所有方面都是函数,与“普通”函数的唯一区别是它们可以被隐式调用并且它们有一个有趣的名字。
某些运算符具有内置含义,可由程序员更改。一种是简单地通过 built-in operator 来指代运算符的内置含义(参见 5/3)。但是,如果这样的运算符应用于定义了内置含义的操作数,则仅允许在少数情况下更改该含义(这些是赋值、地址和逗号运算符,请参阅 13.5/6)。
【讨论】:
以下是运算符和函数之间的一些区别:
运算符不会将其参数压入堆栈,但函数会将其参数压入堆栈。
编译器知道运算符的操作,但不知道函数的输出。换句话说,操作符的动作是在编译时定义的,而函数的动作是在运行时定义的。
【讨论】: