The idea of this thread is to serve as a reference to link when spotting a T *foo = new T; or similar code snip.
It may also include some misconceptions that propitiate the use of such aberration (like the ignorance on initialization list, java background, declaring a function instead of an object)
Code that creates an object using new and then deletes it at the end of the same scope is ugly, error-prone, and inefficient.
ugly: Gadget *p = new Gadget(n);
[sarcasm] c++ is so stupid that you need to tell it twice what you want [/sarcasm]
error prone:
1 2 3 4 5 6 7 8
void foo(int n, int x){
Gadget *p = new Gadget(n);
//...
if(x<100) throw std::run_time_error("weird"); //leak
if(x<200) return; //leak
//...
delete p; //may as well forget this
}
inefficient:
1 2 3 4 5 6 7
void foo(int n, int x){
unique_ptr<Gadget> p = new Gadget(n); //managing that pointer
//...
if(x<100) throw std::run_time_error("weird"); //no leak
if(x<200) return; //no leak
//...
}
- one extra indirection
- cache misses
- dynamic allocation is expensive
Yes. std::array is quite possibly the one and only exception. And that's only because it's designed to function like a lightweight array and not an encapsulated class.
(and yes, I'm aware that basic types like int also behave differently in this case)
// These are the same:
std::string a;
std::string b{};
// So are these:
std::vector<int> a;
std::vector<int> b{};
// And these:
wxWindow a;
wxWindow b{};
// And these:
sf::Sprite a;
sf::Sprite b{};
// And these:
AnyClassIveEverWritten a;
AnyClassIveEverWritten b{};
// the list goes on, and on, and on
EDIT:
To clarify:
Technically you're right. Value initializing and default initializing are different things. I'm not saying you're wrong.