Return automatic local objects in C ++

I am trying to understand some aspects of C ++.

I wrote this short program to show different ways to return objects from functions in C ++:

#include <iostream> 

using namespace std;

// A simple class with only one private member.
class Car{
     private:
        int maxSpeed;
     public:
        Car( int );
        void print();
        Car& operator= (const Car &);
        Car(const Car &);
 };

 // Constructor
 Car::Car( int maxSpeed ){
    this -> maxSpeed = maxSpeed;
    cout << "Constructor: New Car (speed="<<maxSpeed<<") at " << this << endl;
 }

 // Assignment operator
 Car& Car::operator= (const Car &anotherCar){
    cout << "Assignment operator: copying " << &anotherCar << " into " << this << endl;
    this -> maxSpeed = anotherCar.maxSpeed;
    return *this;
 }

 // Copy constructor
 Car::Car(const Car &anotherCar ) {
    cout << "Copy constructor: copying " << &anotherCar << " into " << this << endl;
    this->maxSpeed = anotherCar.maxSpeed;
 }

 // Print the car.
 void Car::print(){
    cout << "Print: Car (speed=" << maxSpeed << ") at " << this << endl;
 }

 // return automatic object (copy object on return) (STACK)
 Car makeNewCarCopy(){
    Car c(120);
    return c; // object copied and destroyed here
 }

// return reference to object (STACK)
Car& makeNewCarRef(){
    Car c(60);
    return c; // c destroyed here, UNSAFE!
    // compiler will say: warning: reference to local variable ‘c’ returned
 }

// return pointer to object (HEAP)
Car* makeNewCarPointer(){
    Car * pt = new Car(30);
    return pt; // object in the heap, remember to delete it later on!
 }

int main(){
    Car a(1),c(2);
    Car *b = new Car(a);
    a.print();
    a = c;
    a.print();

    Car copyC = makeNewCarCopy(); // safe, but requires copy
    copyC.print();

    Car &refC = makeNewCarRef(); // UNSAFE
    refC.print();

    Car *ptC = makeNewCarPointer(); // safe
    if (ptC!=NULL){
        ptC -> print();
        delete ptC;
    } else {
        // NULL pointer
    }
}

The code does not seem to crash, and I get the following output:

Constructor: New Car (speed=1) at 0x7fff51be7a38
Constructor: New Car (speed=2) at 0x7fff51be7a30
Copy constructor: copying 0x7fff51be7a38 into 0x7ff60b4000e0
Print: Car (speed=1) at 0x7fff51be7a38
Assignment operator: copying 0x7fff51be7a30 into 0x7fff51be7a38
Print: Car (speed=2) at 0x7fff51be7a38
Constructor: New Car (speed=120) at 0x7fff51be7a20
Print: Car (speed=120) at 0x7fff51be7a20
Constructor: New Car (speed=60) at 0x7fff51be79c8
Print: Car (speed=60) at 0x7fff51be79c8
Constructor: New Car (speed=30) at 0x7ff60b403a60
Print: Car (speed=30) at 0x7ff60b403a60

Now I have the following questions:

  • Is makeNewCarCopy safe? Is a local object copied and destroyed at the end of the function? If so, why doesn't it call the overloaded assignment operator? Does it invoke the default copy constructor?
  • My courage tells me to use it makeNewCarPointeras the most common way to return objects from a C ++ function / method. I'm right?
+4
source share
3 answers

makeNewCarCopy? ? , ? ?

: " makeNewCarCopy ?" : "". . , , .

, , , , . . , , , . , , , - . , create-copy-destroy , . copy elision. , , (.: As-if Rule) , (. ).

makeNewCarPointer / ++. ?

. , . , . , ( ), , - ?

- . , . , , "", , - , . , (.. "" ).

+5

, makeNewCarCopy . , , , - .

, makeNewCarCopy , Car, makeNewCarCopy Car, .

: , , . , , , Car, , . , std::shared_ptr<Car>.

+1
  • makeNewCarCopy . , , copy elision ( , ctor ) / , ++ 11
  • makeNewCarPointer , . , , . , , std::unique_ptr std::shared_ptr. , , . , .
+1

All Articles