Constructor called on an already created object

Peter Lapisu picture Peter Lapisu · Feb 18, 2011 · Viewed 9.8k times · Source

If I call a constructor on an already constructed object or struct, will it allocate new space, or just use the existing space? So is the first object allocation more resource intensive? Like this:

struct F {
    int a,b,c,d;
    F(int _a, int _b) {a = _a; b = _b}; 
    void a(int _a, int _b) {a = _a; b = _b};
};  

//first constructor call
F f = F(5, 6);

//second constructor call on an already constructed object
f = F(7, 8);

//third constructor call on an already constructed object
f(7, 8);

//is the constructor call more res. intesive, than the call to a function which does the same? 
f.a(9, 0)

Is the constructor call more resource intesive, than the call to a function which does the same (void a(...))?

Does the destructor gets called, when I call a constructor on an already created object?

Answer

In silico picture In silico · Feb 18, 2011

First off, the [c] tag is inappropriate since constructors are a C++-only feature. I'll assume the code snippet you provided is in fact C++ and not some weird dialect of C. C++ and C are different languages; do not tag your questions as both since you will get different answers for each.

Second, your constructor definition is wrong. Constructors must have the exact same name as the class itself. So f() should've been F(). Yes, case-sensitivity matters in C++! I'll assume this is what you meant for the rest of the code snippet. OP simply made a typo.

Before I explain what the rest of your code does, you must understand that all classes (and structs) in C++ have special member functions that are automatically generated by the compiler if you don't provide them. That is, your code snippet is basically the same as:

struct F
{
    F(int _a, int _b) {a = _a; b = _b};  // constructor
    ~F() {}                              // destructor
    F(const F& rhs)                      // copy constructor
        : a(rhs.a)
        , b(rhs.b)
        , c(rhs.c)
        , d(rhs.d)
    {}
    F& operator=(const F& a)             // copy assignment operator
    {
        a = rhs.a;
        b = rhs.b;
        c = rhs.c;
        d = rhs.d;
        return *this;
    }

    void a(int _a, int _b) {a = _a; b = _b};   // one of your functions

    int a;
    int b;
    int c;
    int d;
};

If you do not define a copy constructor, a copy assignment operator, or a destructor, the compiler will generate them for you. Also, if you don't provide some other constructor, the compiler will generate a default constructor. There is no default constructor for class F since there's already a (non-copy) constructor that accepts two arguments.

The default implementation of the copy constructor and the copy assignment operator simply copies each data member.

The reason why special member functions exist is because C++ generalizes the notion of copying primitive types to user defined objects. Consider this:

int a = 42;
int b = 13;
b = a;

With primitive types like ints, you can copy around its value just like that. C++ generalizes the copy semantics to objects so you can do this:

F f(10, 20); // calls first constructor
F g(30, 40); // calls first constructor
g = f;       // calls g's copy-assignment operator.

Now you can see how this applies to your code:

F f = F(5,6); 

The line above constructs a temporary F object, then copies the temporary into f via the copy constructor. The temporary F object is then destructed.

f = F(7,8);

The line above constructs another temporary F object, then assigns the temporary into f via the copy assignment operator. The temporary F object is then destructed. The original f object is not destructed.

f.a(9,0)   

The line above is a normal function call on an object called f.

For your code snippet, assuming compilers do not optimize away the temporaries (they in fact usually do), then calling the function a is "less resource intensive" since no temporaries are made in that case. However, for your first constructor call, you can just do this:

F f(5,6); // Constructor called; no temporaries are made

Understand what constructors are used for: they are used to create objects. If you already have an object, then you don't need to call a constructor.

As I have recommended many times, please pick up a good C++ book and read it. Special member functions and what they do are quite fundamental to C++.