Is that way of using constructor really better ?

Started by
28 comments, last by Servant of the Lord 11 years, 7 months ago
No, it's possible to handle that case, it's just ugly, annoying and doesn't scale well.

Foo::Foo()
try : somePointer(new int[10])
{
// constructor body
} catch (SomeException & s) {
delete [] somePointer;
throw;
}
Advertisement

One gotcha though related to initializer lists is that exception safety is not possible if allocating memory to raw pointers.

....

The above code has a memory leak, somePointer is never freed since construction of Bar throws an exception.

It's true that you can write bad code in any language. In this case, the language is C.

The C++ answer to that is do not use C-style raw pointers.

Bar::Bar()
{
throw SomeException();
}

class Foo
{
std::unique_ptr<int[]> somePointer;
Bar bar;
};

Foo::Foo()
:somePointer(new int[10])
{
}

Foo::~Foo()
{
}

Wow, less code, exception safe.

Of course, there's the response "but I prefer to write bad code and bad code doesn't work, therefore C++ is bad", but all that kind of argument does for me is make me respect you less.

Stephen M. Webb
Professional Free Software Developer


The C++ answer to that is do not use C-style raw pointers.

QFT.
Of course, there's the response "but I prefer to write bad code and bad code doesn't work, therefore C++ is bad"[/quote]

"I get my hands dirty when I try to garden without a shovel!"
Then use a shovel! It's sitting two feet away from you...
"C++ is bad, because it lets you dig with your hands if you want to. *My* language glues the shovel to your hands."

C++ isn't intended to, nor designed for, protecting users from themselves.
Now excuse me while I go try to make a pot of coffee with a shovel still glued to my hands.

If there is a compiler that does not issue a warning when you put initializers out of order, you should switch to one that does.


FYI Visual c++ 2012 does not issue a warning about this with /wall (and 'language extensions' disabled fwiw). I know gcc does, and I agree that it's a useful warning.
[size="1"]


int height = 5ft + 9in;
int weight = 160lbs;


O_o, units!? That would be absolutely awesome. Is this some c++11 thing? How does that work? Ref? (Google gave nothing)

[quote name='Servant of the Lord' timestamp='1349319567' post='4986638']

int height = 5ft + 9in;
int weight = 160lbs;


O_o, units!? That would be absolutely awesome. Is this some c++11 thing? How does that work? Ref? (Google gave nothing)
[/quote]
They are user-defined literals. Note that they should be prefixed with an underscore to be technically right. You have to declare and define the custom literals yourself.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Yep, they are a C++11 feature. Suffixes only, no prefixes at this point. Here's wikipedia's thoughts.
Alas I can't use it yet, since I'm still on MinGW/GCC 4.6, and those (and most of the above C++11 features I mentioned) are on 4.7. sad.png

@Cornstalks: Thanks for the tips about the underscore! The user-defined literals should've also (better/safer coding) returned a user-defined type, like Length, instead of putting it into a generic int: Length myHeight = (4_feet + 8_inches);
Thanks a lot for all those MUCH useful answers ! I didn't even expect to learn so much when I posted this thread. I know everything I wanted to know and even more. Well, I gave most of you +rep. Also you convinced me to use initializer lists more often. It's just drop in the ocean of knowledge I'd like to have, but, well, that's a step. Thank you.

[quote name='Bregma' timestamp='1349356831' post='4986749']
If there is a compiler that does not issue a warning when you put initializers out of order, you should switch to one that does.


FYI Visual c++ 2012 does not issue a warning about this with /wall (and 'language extensions' disabled fwiw). I know gcc does, and I agree that it's a useful warning.
[/quote]
Yeah, msvc is the only compiler I know of that doesn't support that warning. For gcc, clang and intel, the flag is -Wreorder.

You could vote for it if you want Microsoft to add it.
Most modern compilers will optimize the trivial stuff. So I only stick important things (large items, parent classes, references, ect...) in the initializer list, as I really don't like them. My big issue is that the order items are initlialized in the initializer list is not the same order as they are listed. Which for dependent items can really lead to some hard to track down bugs.[/quote]

Why is this being voted down? His gripe about the initialiser list order not being the actual initialisation order is perfectly valid. It's intuitive to assume that the variables are going to be initialised in the order that the initialisation code is written - which is exactly the case whenever you initialise something using the equals sign.

Also mentioned in this topic, ordering your members for alignment or caching reasons can potentially break your code if one member was initialised using the value of another. And since headers are used, the potential error will not even be visible in the file where the initialisation code is actually written.

Personally if I have primitive variables that I need to initialise in a specific order, I'm not going to rely on the class definition order to do it, and that means good old fashioned assignment with the = operator.

This topic is closed to new replies.

Advertisement