samedi 5 septembre 2020

Constructors and temporary objects of C++11 functions

Given :

A class named Object :

##############
#  Object.h  #       
##############

#ifndef OBJECT_H
#define OBJECT_H
#include "string"

class Object {

private:
    static int objectCounter;
    int id;
    std::string name;
    std::string copyOf;

protected:
    int x;

public:
    Object(int x);
    Object(const Object& object);
    virtual ~Object();
    virtual void isCopy();
    virtual void print();
    Object& operator=(const Object& object);
};


#endif


##############
# Object.cpp #       
##############

#include "Object.h"
#include "iostream"

using namespace std;
int Object::objectCounter = 1;

Object::Object(int x) : x(x) {

    id = objectCounter;
    objectCounter++;
    name = "Object_" + to_string(id);
    copyOf = "";
    cout << name + " has been created by DC" << endl;
}

Object::Object(const Object &object) {
    id = objectCounter;
    objectCounter++;
    copyOf = object.name;
    name = "Object_" + to_string(id);
    cout << name + " which is a copy of " + copyOf + " has been created by CC" << endl;
}

void Object::isCopy() {

    if (copyOf.length() == 0)
        cout << name + " is not a copy of anything " << endl;
    else
        cout << name + " is a copy of " + copyOf << endl;
}

void Object::print() {
    cout << "----" << endl;
    cout << name << endl;
    isCopy();
    cout << "Object_X : " << x << endl;
}


Object::~Object() {
    if (copyOf.length() == 0)
        cout << name + " has been destroyed" << endl;
    else
        cout << name + " which is a copy of " + copyOf + " has been destroyed" << endl;

}

Object& Object::operator=(const Object &object) {

    if (&object == this)
        cout << "Can't assign " + name + " to itself" << endl;
    else {
        cout << "Assigning " + object.name + " to " + name << endl;
        x = object.x;
    }

    return *this;
}


main_1 :

Object function() {
    Object object(10);
    return object;
  }

  int main() {

    Object object1 = function();

}

#####

Execution :

Object_1 has been created by DC
Object_1 has been destroyed

main_2 :

  Object function(Object object) {
    return object;
  }

  int main() {

    Object object1(1);
    Object object2 = function(object1);

  }

##########

Execution :

Object_1 has been created by DC
Object_2 which is a copy of Object_1 has been created by CC
Object_3 which is a copy of Object_2 has been created by CC
Object_2 which is a copy of Object_1 has been destroyed
Object_3 which is a copy of Object_2 has been destroyed
Object_1 has been destroyed

Using the C++11 Standard I encountered an odd behavior.

When it comes to main_1 :

I guess it's a kind of optimization and it's like ok a temporary Object object is created inside the function so C++ might as well keep it instead of deleting it.

When it comes to main_2 :

A temporary Object object is created once again cause of the function's argument but this time the copy constructor is invoked instead of acting the same way.Why is that? My only guess is that it has something to do with the one being an Object object declared inside the function and the other being an argument of the function

Any insight would be really helpful.Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire