c++ operator overloading memory question

后端 未结 6 2039
挽巷
挽巷 2021-01-01 07:44

In c++ you can create new instances of a class on both the heap and stack. When overloading an operator are you able to instantiate on the stack in a way that makes sense?

6条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-01 08:12

    C++ : RAII and Temporaries

    You're right about objects on stack being destroyed once going out of scope.

    But you ignore that C++ will use temporary objects are necessary. You must learn when a temporary variable will be created (and then optimized away) by the compiler for your code to work.

    Temporary Objects

    Note that in the following, I'm describing a very simplified "pure" viewpoint of what's happening: Compilers can and will do optimizations, and among them, will remove useless temporaries... But the behavior remains the same.

    Integers?

    Let's start slowly: What is supposed to happen when you play with integers:

    int a, b, c, d ;
    // etc.
    a = b + (c * d) ;
    

    The code above could be written as:

    int a, b, c, d ;
    // etc.
    int cd = c * d ;
    int bcd = b + cd ;
    a = bcd ;
    

    Parameters by value

    When you call a function with a parameter passed "by value", the compiler will make a temporary copy of it (calling the copy constructor). And if you return from a function "by value", the compiler will, again, make a temporary copy of it.

    Let's imagine an object of type T. The following code:

    T foo(T t)
    {
       t *= 2 ;
    
       return t ;
    }
    
    void bar()
    {
       T t0, t1 ;
    
       // etc.
    
       t1 = foor(t0) ;
    }
    

    could be written as the following inlined code:

    void bar()
    {
       T t0, t1 ;
    
       // etc.
    
       T tempA(t1)     // INSIDE FOO : foo(t0) ;
       tempA += 2 ;    // INSIDE FOO : t *= 2 ;
       T tempB(tempA)  // INSIDE FOO : return t ;
    
       t1 = tempB ;    // t1 = foo...
    }
    

    So, despite the fact you don't write code, calling or returning from a function will (potentially) add a lot of "invisible code", needed to pass data from one level of the stack to the next/previous.

    Again, you need to remember that the C++ compiler will optimize away most temporary, so what could be seen as an innefficient process is just an idea, nothing else.

    About your code

    Your code will leak: You "new" an object, and don't delete it.

    Despite your misgivings, the right code should be more like:

    Point Point::operator+ (Point a)
    {
       Point c = Point(this->x+a.x,this->y+ a.y) ;
       return c ;
    }
    

    Which with the following code:

    void bar()
    {
        Point x, y, z ;
        // etc.
        x = y + z ;
    }
    

    Will produce the following pseudo code:

    void bar()
    {
        Point x, y, z ;
        // etc.
        Point tempA = z ;  // INSIDE operator + : Point::operator+ (Point a)
        Point c = z ;      // INSIDE operator + : Point c = Point(this->x+a.x,this->y+ a.y) ;
        Point tempB = c ;  // INSIDE operator + : return c ;
    
        x = tempB ;        // x = y + z ;
    }
    

    About your code, version 2

    You make too much temporaries. Of course, the compiler will probably remove them, but then, no need to take sloppy habits.

    You should at the very least write the code as:

    inline Point Point::operator+ (const Point & a)
    {
       return Point(this->x+a.x,this->y+ a.y) ;
    }
    

提交回复
热议问题