CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 25 of 25
  1. #16
    Join Date
    May 2004
    Location
    Norway
    Posts
    655

    Re: Can a construction function call another construntor ?

    Quote Originally Posted by NMTop40
    Maybe someone who knows the standard well can answer this question.
    Well, I'm no standards wiz, but I am fairly certain that a temporary should only stay alive as long as the expression it's in (i.e. to the ; after it). (EDIT: Unless it's bound to a const reference) If you want an object to live longer than that, you have to name it. To me that makes sense as you wouldn't need the object to stay alive any longer, as you can't access it. (Though your lock example would be a good use for something like that.)
    Insert entertaining phrase here

  2. #17
    Join Date
    Jun 2002
    Location
    Moscow, Russia.
    Posts
    2,176

    Re: Can a construction function call another construntor ?

    I think it should (effectively) stay for entire function, but in certain cases it can be changed by compiler the way it wouldn't make difference.
    "Programs must be written for people to read, and only incidentally for machines to execute."

  3. #18
    Join Date
    May 2005
    Location
    United States
    Posts
    526

    Re: Can a construction function call another construntor ?

    Quote Originally Posted by NoHero
    Dito. Did you even read my post? I said that it would only create a temporary instance of the class A.
    I'm sorry if I misunderstood you, NoHero. I did read your post, but although you said a temporary instance of A would be created, I wasn't clear on when that temporary would be destroyed. Like NMTop40, I would have expected it to be destroyed at the end of the function, and the fact that it was destroyed earlier surprised me.

  4. #19
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Can a construction function call another construntor ?

    The lock example is just one example of creating an RAII object. Sometimes these objects may be a really complex template type that a user would not want to bother to type out. For example, a scoped-closer:

    Code:
    template < typename T, typename Cl >
    class AutoCloser
    {
    private:
       Cl m_cl;
       T& m_t;
    public:
       AutoCloser( Cl cl, T t ) : m_cl( cl ), m_t( t )
       {
       }
    
       ~AutoCloser()
       {
            m_cl( t );
        }
    };
    
    template < typename T, typename Op, typename Cl, typename P >
    boost::shared_ptr< AutoCloser< T, Cl > > AutoOpen( T&t, Op op, Cl cl, P p)
    {
       t = op( p );
       return new AutoCloser<T, Cl>( t, cl ); // uses implicit constructor
    }
    The template AutoCloser should call cl(t) when it is destructed, where cl is a "close" function. AutoOpen is a function that opens t by calling t = op(p). (Note you can have other AutoOpen functions with the same AutoCloser).

    It returns a boost::shared_ptr to a class but for any user to have to specify the type, which would include the type of the function cl, gets rather complicated.

    (Note, I worked around this problem by creating a class called AutoCloserBase, then you derive your AutoCloser template from it, and use a shared_ptr<AutoCloserBase> which is easy enough for any user to type out. The destructor of AutoCloserBase is virtual, of course, so your destructor does get called as appropriate).

  5. #20
    Join Date
    Apr 2005
    Location
    INDIA
    Posts
    35

    Re: Can a construction function call another construntor ?

    In ur derived class constructor u can call the base class contructor as follows:

    class base
    {
    .......
    base{}
    };

    class der
    {
    ........
    der( a,b:base(c))
    {}
    };

  6. #21
    Join Date
    Mar 2004
    Location
    (Upper-) Austria
    Posts
    2,899

    Re: Can a construction function call another construntor ?

    Quote Originally Posted by Smasher/Devourer
    I'm sorry if I misunderstood you, NoHero. I did read your post, but although you said a temporary instance of A would be created, I wasn't clear on when that temporary would be destroyed. Like NMTop40, I would have expected it to be destroyed at the end of the function, and the fact that it was destroyed earlier surprised me.
    I meant temporary because you cannot access this object. Well "temporary" was a bad word choice too.
    I am not offering technical guidiance via email or IM
    Come on share your photo with us! CG members photo album!
    Use the Code Tags!

  7. #22
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Can a construction function call another construntor ?

    Quote Originally Posted by pranavsharma
    In ur derived class constructor u can call the base class contructor as follows:

    class base
    {
    .......
    base{}
    };

    class der
    {
    ........
    der( a,b:base(c))
    {}
    };
    No you can't. There are a lot of syntactical errors in there.

    The constructor of der may call a constructor of base in its initialiser list, if it doest not with to use the default constructor of base. If base does not have a default constructor, or if the default constructor is private, then der MUST call another constructor of base in its initialiser list.

    The copy-constructor of der will invoke the copy constructor of base unless overridden (in the initialiser list) to do otherwise.

    What you might have meant was:

    Code:
    class base
    {
     public: // or protected
        base( int b );
    };
    
    class der : public base // or inheritance private or protected
    {
    public:
       der ( int a, int b ) : base( b ) // , other initialisations
       {
       }
    };
    Note that the base class is always constructed first. Thus you can't do this:
    Code:
    class der : public base // or inheritance private or protected
    {
    private:
       int b;
    public:
       der ( int a ) : b( a*a), base( b )  
       {
       }
    };
    The code above would compile but it would ignore the ordering in your initialiser list and construct base first from an uninitialised variable.

  8. #23
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: Can a construction function call another construntor ?

    Quote Originally Posted by RoboTact
    I think it should (effectively) stay for entire function, but in certain cases it can be changed by compiler the way it wouldn't make difference.
    The lifetime of each variable is really important and well defined by the standard.
    When a temporary object is constructed in a statement, it is destroyed just before the next statement.
    When a variable is declared in a code block (any piece of code between '{' and '}' characters), it is destoyed at the end of the code block.
    Moreover objects are destroyed in the reverse order they are declared in the code block.
    For example:
    Code:
    void f()
    {
    
    if (something)
    {
    std::string x=/*...*/;
    AFunction(ClassNeedingAStringAndUsingThisStringDuringAllHisLifeTime(x.c_str()));
    // Some code here...
    } // x destroyed
    else
    {
    // some code here : if the condition is false, x is never constructed
    }
    
    }
    You see that if ClassNeedingAStringAndUsingThisStringDuringAllHisLifeTime was destroyed after x (for example at the end of the function), it will probably crash, because the destructor of this class supposes that the const char* string passed in his constructor is valid.

    A more realistic example, is the use of ostream:
    Code:
    void AFunction()
    {
    MyStreamBufImplementation buf;
    ostream output(&buf);
    output<<"some string put in the buffer and not yet flushed";
    } // at this position if buf was destroyed before output it will crash when output is destroyed, because ostream::~ostream flushes the buffer on an invalid (already destroyed) streambuf object.
    Last edited by SuperKoko; July 11th, 2005 at 06:01 AM.

  9. #24
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: Can a construction function call another construntor ?

    The temporary lasts until the end of the expression it's created in, unless it's bound to a const reference, in which case, it has the lifetime of the reference.
    Standard, 12.2/3:
    [...]Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. [...]
    And paragraphs 4 & 5:
    4 There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. The first context is when an expression appears as an initializer for a declarator defining an object. In that context, the temporary that holds the result of the expression shall persist until the object’s initialization is complete. [...]

    5 The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below. [...]
    (The exceptions are mostly just clarifications and don't make much difference to the argument.)
    Code:
      A::A(a);    // Dies almost immediately
      const A& r = A::A(a); // Dies when r goes out of scope
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  10. #25
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Can a construction function call another construntor ?

    When a temporary object is constructed in a statement, it is destroyed just before the next statement.
    When a variable is declared in a code block (any piece of code between '{' and '}' characters), it is destoyed at the end of the code block.
    Thank-you. The first statement answers my question. Thus my first example of using AutoMutexLock won't work and you must assign a variable to it as with the second example.
    And that would also explain why when using a function like AutoOpen() you have to assign the return value. (As it happens though, the shared pointer to the AutoCloseBase will work with ANY object that we wish to use simply for RAII, and AutoCloseBase is a totally empty class with nothing but an empty virtual destructor. In fact, by typedef'ing the shared pointer to it, which I have done, your programmers don't even have to know you are using boost::shared_ptr).

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured