Does New[] Call Default Constructor in C++

Does new[] call default constructor in C++?

See the accepted answer to a very similar question. When you use new[] each element is initialized by the default constructor except when the type is a built-in type. Built-in types are left unitialized by default.

To have built-in type array default-initialized use

new int[size]();

Does the `new` operator always call the constructor?

If you search for constructor on the linked MSDN page, it says this:

When new is used to allocate memory for a C++ class object, the object's constructor is called after the memory is allocated.

In other words, a constructor is called if one exists. If none exists, none is called.

Object array initialization without default constructor

Nope.

But lo! If you use std::vector<Car>, like you should be (never ever use new[]), then you can specify exactly how elements should be constructed*.

*Well sort of. You can specify the value of which to make copies of.


Like this:

#include <iostream>
#include <vector>

class Car
{
private:
Car(); // if you don't use it, you can just declare it to make it private
int _no;
public:
Car(int no) :
_no(no)
{
// use an initialization list to initialize members,
// not the constructor body to assign them
}

void printNo()
{
// use whitespace, itmakesthingseasiertoread
std::cout << _no << std::endl;
}
};

int main()
{
int userInput = 10;

// first method: userInput copies of Car(5)
std::vector<Car> mycars(userInput, Car(5));

// second method:
std::vector<Car> mycars; // empty
mycars.reserve(userInput); // optional: reserve the memory upfront

for (int i = 0; i < userInput; ++i)
mycars.push_back(Car(i)); // ith element is a copy of this

// return 0 is implicit on main's with no return statement,
// useful for snippets and short code samples
}

With the additional function:

void printCarNumbers(Car *cars, int length)
{
for(int i = 0; i < length; i++) // whitespace! :)
std::cout << cars[i].printNo();
}

int main()
{
// ...

printCarNumbers(&mycars[0], mycars.size());
}

Note printCarNumbers really should be designed differently, to accept two iterators denoting a range.

Why explicitly call a constructor in C++

Most often, in a child class constructor that require some parameters :

class BaseClass
{
public:
BaseClass( const std::string& name ) : m_name( name ) { }

const std::string& getName() const { return m_name; }

private:

const std::string m_name;

//...

};

class DerivedClass : public BaseClass
{
public:

DerivedClass( const std::string& name ) : BaseClass( name ) { }

// ...
};

class TestClass :
{
public:
TestClass( int testValue ); //...
};

class UniqueTestClass
: public BaseClass
, public TestClass
{
public:
UniqueTestClass()
: BaseClass( "UniqueTest" )
, TestClass( 42 )
{ }

// ...
};

... for example.

Other than that, I don't see the utility. I only did call the constructor in other code when I was too young to know what I was really doing...

Can I call a constructor from another constructor (do constructor chaining) in C++?

C++11: Yes!

C++11 and onwards has this same feature (called delegating constructors).

The syntax is slightly different from C#:

class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};

C++03: No

Unfortunately, there's no way to do this in C++03, but there are two ways of simulating this:

  1. You can combine two (or more) constructors via default parameters:

    class Foo {
    public:
    Foo(char x, int y=0); // combines two constructors (char) and (char, int)
    // ...
    };
  2. Use an init method to share common code:

    class Foo {
    public:
    Foo(char x);
    Foo(char x, int y);
    // ...
    private:
    void init(char x, int y);
    };

    Foo::Foo(char x)
    {
    init(x, int(x) + 7);
    // ...
    }

    Foo::Foo(char x, int y)
    {
    init(x, y);
    // ...
    }

    void Foo::init(char x, int y)
    {
    // ...
    }

See the C++FAQ entry for reference.



Related Topics



Leave a reply



Submit