views:

371

answers:

5

I'm learning C++ at the moment, C++ Primer plus. But I just felt like checking out the cplusplus website and skip a little forward to file handling.

I pretty much know the basics of file handling coming from java, php, visual basic. But I came across a pretty weird line.

ostream os(&fb);

fb represents a filebuf. I just don't get the syntax of this, but I can figure out that it's the same as:

ostream os = &fb;

But I never really read about this way of initializing variables.

So I'm wondering. Am I just senseless and missing out a real useful feature the entire time? Is this way of initializing just old? Is it something different?

Thanks in advance.

+6  A: 

Perhaps you should read this and this

helium
Thank you for this great reference and quick answer :)
Jeffrey Vandenborne
You should provide the answer here, in this post. The link might be down when someone else needs this question answered, and hey, if you want the rep, you should post the actual answer. It's common SO courtesy.
jalf
Lightly paraphrased from the second link: `ostream os =
Mike D.
In this case, of course, `ostream os = ` will fail, since the stream can't be copied. Wondering why the question doesn't mention that.
Johannes Schaub - litb
+4  A: 

A small program to see when copy constructor is called and when overloaded assignment operator function is called:

#include <iostream>

using namespace std;

class test
{
    public:
     // default constructor.
     test()
     {
      cout<<"Default Ctor called"<<endl;
     }

     // copy constructor.
     test(const test& other)
     {
      cout<<"Copy Ctor called"<<endl;
     }

     // overloaded assignment operator function.
     test& operator=(const test& other)
     {
      cout<<"Overload operator function called"<<endl;
      return *this;
     }
};

int main(void) 
{
    test obj1;  // default constructor called.

    test obj2 = obj1; // copy constructor called.

    test obj3(obj2); // again copy constructor called.

    obj1 = obj2; // overloaded assignment operator function.

    return 0;
}

Output:

Default Ctor called
Copy Ctor called
Copy Ctor called
Overload operator function called

So in your case, the copy constructor of ostream is called in both the occasions.

codaddict
Seems I was pretty correct then :D. Thanks for the clear explanation. Happy holidays!
Jeffrey Vandenborne
+3  A: 

Both forms perform initialization. The first syntax (with ()) is called direct-initialization syntax. The second syntax (with =) is called copy-initialization syntax. They will act same in most real-life cases, but there are indeed differences between the two.

In situations when types on the left-hand side (LHS) and right-hand side (RHS) are identical (ignoring any const/volatile qualifiers), both are indeed exactly the same. The language standard explicitly states that in this case the = form is equivalent to () form.

But when the types are different (and the LHS type is a class type), these two forms will generally work differently.

  • The copy-initialization form works as follows: convert the RHS value to the temporary object of LHS type (by any means possible: standard conversion, conversion operator, conversion constructor). And then use the copy constructor of the LHS class to copy the temporary object to the LHS object.

  • The direct initialization form work as follows: just consider all constructors of LHS and choose the most appropriate one by using overload resolution.

You can immediately notice that the copy-initialization syntax unconditionally uses the copy constructor (the copying and the intermediate temporary can be optimized away, but conceptually they are there). If the LHS class has no accessible copy-constructor, the copy-initialization unconditionally becomes ill-formed, while direct-initialization might still work.

Also, the keyword explicit applied to certain constructor will affect which form of initialization is available for which combinations of types.

AndreyT
Just going to pick on that *exactly* word (since the answer sounds like it's going for a really standard's answer): If the copy constructor is explicit, then the `=` syntax will fail in the case LHR and RHS are the same type, while the `()` form will not fail.
Johannes Schaub - litb
A: 
Algorist
No, `
R Samuel Klatchko
I edited my answer. please check it.
Algorist
+1  A: 

One important benefit of function-call initialization is that they also work with constructors that take multiple arguments. For example, an fstream constructor can take two parameters:

std::fstream file("filename", ios_base::out);

Until C++0x uniform initialization is widely available, function-call initialization is the only way to handle multiple argument constructors.

R Samuel Klatchko