【问题标题】:Difference between operator and function in C++?C++中运算符和函数的区别?
【发布时间】:2011-06-10 01:05:25
【问题描述】:

我可以使用一些帮助来理解 C++ 中的以下内容,尤其是运算符和函数之间的区别:

  • 什么是运算符?
  • 什么是函数?
  • 它们之间有什么区别?
  • 用户定义的operator+()函数还是运算符
  • 运算符可以在编译时对操作数进行操作吗?它们总是在编译时运行吗? (如 C++ 中的 sizeof()

【问题讨论】:

    标签: c++ operators user-defined-functions


    【解决方案1】:

    在 C++ 中,您可以覆盖符号 +、-、== 等应用于类实例时的作用。通过在 A 类中定义“operator+”方法,您可以告诉编译器如何处理如下代码:

    A a, b, c;
    c = a + b; // the + here actually calls a.operator+(b)
    

    它也是一个函数,或者更准确地说是一个实例方法,在某种意义上它是被调用的东西。

    编辑:另见http://en.wikipedia.org/wiki/Operator_overloadinghttp://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading

    【讨论】:

      【解决方案2】:

      运算符和函数之间没有任何意义的区别,只是运算符的语法不同。然而,原始运算符不是函数。

      【讨论】:

        【解决方案3】:

        函数和运算符之间没有太大的区别。您可以将 using 运算符(例如 'a+b')视为函数 operator+(a,b) 的快捷方式,该函数是为 a 和 b 的类型定义的。当然,原始类型(如整数)的运算符和其他一些例外情况不一定要这样定义。

        因此,回答您的一些具体问题:

        自定义operator+()是函数还是运算符?

        实现运算符的函数。

        运算符可以在编译时对操作数进行操作吗?它们总是在编译时运行吗?

        由于它是一个函数,它在运行时运行,但在某些情况下,编译器优化可以在编译时对某些运算符起​​作用。我不是 100% 确定你为什么要问这个,所以也许这里有一些我不知道的东西。

        【讨论】:

          【解决方案4】:

          什么是运算符?

          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())一样获取其地址。
          • @Martin York:它确实具有函数调用的语义,但这并不意味着它是一个函数。例如,您不能使用 std::mem_fun_ref 调用运算符重载。
          • 可能你可以。问题不在于重载的运算符,而在于 mem_fun_ref 不能采用具有引用参数的方法(众所周知 mem_fun_ref 失败)。您可以像使用任何其他方法一样获取 X::operator+() 的地址,并像使用其他方法一样使用它。
          • @Martin:我不知道你可以这样称呼它。
          【解决方案5】:

          函数和运算符之间只有两个细微差别。

          1. 运算符可以以两种方式使用(x+yoperator+(a,b))。
          2. 运算符必须具有与内置参数相同数量的参数(operator== 必须恰好有两个参数)。此规则的例外是函数调用 operator(),它可以使用任意数量的任意参数进行重载。

          【讨论】:

            【解决方案6】:

            什么是运算符?

            运算符是在表达式中使用的符号。
            例如:+ - * / 等

            在内置类型上,操作定义明确且不可更改。
            对于用户定义的类型,运算符可以定义为函数/方法调用的语法糖

            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));
            }
            

            【讨论】:

              【解决方案7】:

              运算符 是一个符号,如+-+= 等等(参见 13.5)。它们没有任何意义。在语义分析期间,确定运算符的含义。

              函数是构造函数、析构函数、转换函数(看起来像operator type())或运算符函数(函数模板专门化和实例化可以依次产生这些)。

              运算符函数实现运算符的东西(见13.5)。一个例子是operator+。这些在所有方面都是函数,与“普通”函数的唯一区别是它们可以被隐式调用并且它们有一个有趣的名字。

              某些运算符具有内置含义,可由程序员更改。一种是简单地通过 built-in operator 来指代运算符的内置含义(参见 5/3)。但是,如果这样的运算符应用于定义了内置含义的操作数,则仅允许在少数情况下更改该含义(这些是赋值、地址和逗号运算符,请参阅 13.5/6)。

              【讨论】:

                【解决方案8】:

                以下是运算符和函数之间的一些区别:

                1. 运算符不会将其参数压入堆栈,但函数会将其参数压入堆栈。

                2. 编译器知道运算符的操作,但不知道函数的输出。换句话说,操作符的动作是在编译时定义的,而函数的动作是在运行时定义的。

                【讨论】:

                • 你的两个观点在 C++ 中都是错误的 - 运算符重载开始发挥作用。
                猜你喜欢
                • 2012-03-19
                • 2013-06-05
                • 2014-10-28
                • 2021-11-08
                • 1970-01-01
                • 2012-03-20
                • 2013-07-06
                • 2019-09-25
                相关资源
                最近更新 更多