浅谈C++中如何重载前置++/--与后置++/--

前置++/–与后置++/–

C++中的++和–操作符存在前置式与后置式,最基本的,作为一名程序员,你应当了解它们实现的不同:

i++;
++i;

以上两行代码如果单独使用,在功能上是一致的,它们都实现了让变量i加1的操作,但是实现的机制有所不同:

  • i++是先用后加,即你在t时刻得到的变量i的值实际上还是原来的值,但它实际的值已经被加1;
  • ++i是先加后用,即你用的值和变量i当前时刻的值是一样的;
    int a = 1;
    int b = 1;

    cout << "a: " << a << "   前++: " << ++a << "   a:" << a << std::endl;
    cout << "b: " << b << "   后++: " << b++ << "   b:" << b << std::endl;

运行结果:

a: 1++: 2   a:2
b: 1++: 1   b:2

发现没有?后置式其实是将变量的值找了个临时变量先存了起来,然后再将该变量加1,而前置式则直接将变量加1。

从这个机制上,可以下个结论,后置式在性能上要逊与前置式。这其实也是在建议你,在写for循环时尽量使用前置式++i,而不是后置式i++。

前置++/–与后置++/-- 的重载

C++允许这两个操作符拥有重载能力。但是这时候你可能发现在语法上似乎出现了问题:重载函数是以其参数类型或个数来区分彼此的,然而这是个单目运算符,无论是前置式还是后置式,都没有参数。于是,为了填平这个语言上的漏洞,只好让后置式有一个int自变量,在其被调用的时候,编译器默默为该int指定一个0值。

假设我们有一个复数类complex,现在为其重载++运算符:

class complex
{
    
    
public:
    complex& operator++()
    {
    
    
        a = a+1;
        b = b+1;
        return *this;
    };

    const complex operator++(int)
    {
    
    
        complex temp = *this;
        ++temp;
        return temp;
    };

    int a = 0;
    int b = 0;
};

其实,前置++与后置++的功能”先加后用“与”先用后加“已经为这两种操作符的实现指明了路线:既然是先加后用,那加完之后的和最后使用的应当是同一样东西,所以应当返回引用。同理,”先用后加“说明应当先把原来的值保存起来,再将其加1,但是最后还是应当返回其原来的值,因为是”先用后加“嘛。另外,你还应当注意,这里保存完原来的值之后,直接调用了前置++去实现加1,这种操作很好的实现了复用,应当被提倡。

但是,你可能会奇怪:为什么后置++必须返回一个const值?而不是像前置++一样返回引用就好了?

首先,返回值是因为这是个局部变量,一旦出了作用域,temp的生命周期就完结了,也就不存在引用了;其次,const 其实是在像”偶像”致敬。偶像?谁是偶像?int。

是的,当你不清楚你的实现应当跟谁保持一致的时候,去看看标准库里的数据类型,int类型支持++ ++ i,但是不支持i++ ++。所以,为了跟标准保持一致,建议像偶像看起。因此,返回const值也就说得通了。

最后,附上源码:

#include <iostream>

class complex
{
    
    
public:
    complex& operator++()
    {
    
    
        a++;
        b++;
        return *this;
    };

    const complex operator++(int)
    {
    
    
        complex temp = *this;
        ++temp;
        return temp;
    };

    int a = 0;
    int b = 0;
};

std::ostream& operator<<(std::ostream& os, const complex& value)
{
    
    
    os << value.a << " " << value.b << " ";
    return os;
}

int main()
{
    
    
    int a = 1;
    int b = 1;

    cout << "a: " << a << "   前++: " << ++a << "   a:" << a << std::endl;
    cout << "b: " << b << "   后++: " << b++ << "   b:" << b << std::endl;
    complex c;
    cout << "c:  " << c << "   前++++:   " << ++ ++c << "  后++   " << c++ << std::endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43717839/article/details/134652105