views:

829

answers:

4

Hello, I'm new to C++ and I have a question...

I tried answering the question myself by making a test application... in debug, the class B initialization generates less assembly code, but in release mode, I can't really say... it optimizes the initializations away :(

Let's say I have two classes:

class A
{
public:
    int a, b, c, d;

    A(int _a, int _b, int _c, int _d) : a(_a), b(_b), c(_c), d(_d)
    {
    }
};

class B
{
public:
    int a, b, c, d;
};

Is there any advantage of using

B b = {1, 2, 3, 4}

instead of

A a = A(1, 2, 3, 4);

?

+2  A: 

I don't know about performance advantages, but in general using the constructor is preferred.

This is because with A, members a,b,c,d can be made private. Thus, you get encapsulation with your A approach, which you don't have in B.

As a class designer, you can enforce strict usage and assignment of member variables via a constructor. In your B, class scenario, you can't.

So while you may get a small boost in perf, for using B, I would wager it to be negligible, and would be negated by the potential headache of having unprotected class members.

Alan
A and B will never change, and nothing will ever inherit from them. Basically, those are vector classes, and will be used a lot, but nothing should ever be protected/private, and no additional members will ever be added. The class will also be extensively used, so that's why I'm wondering if there's a performance boost using the B approach.
Kevin
Whether or not there's a performance boost would almost certainly depend upon the compiler you're using. There aren't any real guarantees here: it depends on your compiler. I'd expect that most compilers would optimize A down to pretty much the same, if not exactly the same, code as B.
Laurence Gonsalves
A: 

Most classes can't use initialization lists (yet!), so you are better off using a constructor just to be consistent. In c++0x std::initializer_list will exist to allow this syntax for any class.

rlbond
+1  A: 

You don't have to explicitly write the constructor and C code using this type of initialization works in C++.

If you have complicated compound structures of simple data fileds, initialization of variables can be easier with initialization lists than with constructors:

B barr[5] = {
    {1,2,3,4},
    {5,6,7,8},
    ...
  };

The disadvantage that it (currently) only works for simple classes with only POD member variables and that programmers might not be very familiar with the syntax.

sth
+2  A: 

For a global objects and static class members, the initializer list doesn't invoke any code on run time. (Initialization data is stored directly in the binary).

If you are initializing a lot of objects, or if the constructor code is expensive / large, this can make a notable difference at load time.

As said, this is true only for plain old data, i.e. everything that can be initialized with an initializer list in C++ < 0x

peterchen
Yes, i think this is THE major advantage of aggregate initialization with constant expressions: Those are static-initialized and you will not encounter the static initialization order fiasco, since when code runs, it will find the struct already initialized.
Johannes Schaub - litb
Great answer, and this is a very useful technique. An additional caveat: I work on code that uses this technique extensively, and I've seen initializer lists invoke code at runtime when the structure contains floating point numbers (with MSVC 7.1). This also causes const structures that contain floating point numbers to be placed into the read/write data section instead of the read-only data section. Perhaps this has something to do with FPU exceptions or rounding?
bk1e
That sounds strange but interesting, bk1e - but i have no giood idea how to explore that. Do oyu have a repro?
peterchen