warum bevorzugt tante erna "new T" vor "new T()" ?



  • gegeben sei folender code:

    template<class T,size_t SIZE>
    class Vector{
    ...
    	Vector::Vector(){
    		size_t i;
    		try{
    			for(i=0;i<SIZE;++i)
    				new(data()+i)T();
    		}
    		catch(...){
    			while(i){
    				--i;
    				data()[i].~T();
    			}
    		}
    	}
    

    solche Vectoren legen sowohl af dem stack als auch auf im freispeicher und sollen möglichst ähnlich den eingebauten arrays sein. und sollen die eingebauten arrays vollständig ersetzen (aber mit assert an den klugen stellen).
    und ich erinnere mich genau daran, daß tante erna sagte,

    new(date()+i)T;
    

    sei besser als

    new(date()+i)T();
    

    allerdings habe ich glatt vergessen, warum das so ist. findet einer vor samstag, wenn ich sie wieder sehe, raus, warum das besser ist?





  • Hallo Volkard,

    vielleicht verwechselst du das hiermit: ?

    Problem
    What is the difference, if any, between the following?

    SomeType t = u;
    SomeType t(u);
    SomeType t();
    SomeType t;

    Solution
    Taking them in reverse order:

    SomeType t;
    The variable t is initialised using the default ctor SomeType::SomeType().

    SomeType t();
    This was a trick; it might look like a variable declaration, but it's a function declaration for a function t that takes no parameters and returns a SomeType.

    SomeType t(u);
    This is direct initialisation. The variable t is initialised using SomeType::SomeType(u).

    SomeType t = u;
    This is copy initialisation, and the variable t is always initialised using SomeType's copy ctor. (Even though there's an "=" there, that's just a syntax holdover from C... this is always initialisation, never assignment, and so operator= is never called.)

    Semantics: If u also has type SomeType, this is the same as "SomeType t(u)" and just calls SomeType's copy ctor. If u is of some other type, then this is the same as "SomeType t( SomeType(u) )"... that is, u is converted to a temporary SomeType object, and t is copy-constructed from that.

    Note: The compiler is actually allowed (but not required) to optimize away the copy construction in this kind of situation. If it does optimize it, the copy ctor must still be accessible.

    [Guideline] Prefer using the form "SomeType t(u)". It always works wherever "SomeType t = u" works, and has other advantages (for instance, it can take multiple parameters).

    und was mir gerade einfällt,
    könnte durch T();
    nicht auch ein solcher konstruktor aufgerufen werden:
    T::T(int i = 0);

    ?

    vielleicht hats geholfen.

    k.



  • Hallo,
    die relevanten Stellen im Standard sind 5.3.4/p15 und 8.5/p5.
    Wenn ich das richtig interpretiere:
    new T(): Immer Default-Initialization.
    new T: Default-Initialization für non-Pods. *Keine* Initialisierung für PODs.

    Default-Initialization:
    Aufruf des Default-Ctors für Non-PODs. Zero-Initialization für PODs.

    new T() führt also zu einer unnötigen Initialisierung von POD-Typen und ist insofern möglicherweise langsamer als new T.
    Allerdings macht das längst nicht jeder Compiler so. Für den VC 6.0 ist new int und new int() z.B. das selbe. Da findet keine Zero-Initialization statt.



  • Auch ganz interessant:
    Das Ende dieser Diskussion


Anmelden zum Antworten