Thread: Constructor calling another constructor?

  1. #1
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545

    Constructor calling another constructor?

    I thought this was possible (and I don't see why it wouldn't be), but VC++ gives me a
    error C2614: 'TicketComparator' : illegal member initialization: 'TicketComparator' is not a base or member
    with the following code:
    Code:
    class TicketComparator
    {
    public:
    	TicketComparator( const std::set<int>*  winningNumbers,
    				std::set<int>*  matchingNums )
    		:	m_WinningNumbers( winningNumbers ),
    			m_MatchingNums( matchingNums ) {}
    
    	TicketComparator( TicketComparator&  rhs )
    		:	TicketComparator( rhs.m_WinningNumbers, rhs.m_MatchingNums ) {}
    ...
    };
    Am I doing something wrong, or is calling a constructor from another constructor not allowed?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You can call a constructor from a constructor, but not from an initializer, I don't think.

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by tabstop View Post
    You can call a constructor from a constructor, but not from an initializer, I don't think.
    Base class constructors can be called in the initializer list of a derived class' constructor. Because copy constructors are also constructors, they can have an initializer list.

    But copy constructors should call their members' copy constructors if possible. If that's not possible, that means that you have to do a deep copy of some pointer, probably. It would be better to use a smart pointer based on whatever your needs may be, due to the fact that smart pointers are easy to reassign and handle their own object.

    There's one ugly way to do it if you have to use a raw pointer. From memory:
    Code:
    class TicketComparator
    {
    public:
        TicketComparator ( const TicketComparator & rhs )
        {
            delete m_matchingNumbers;
            delete m_winningNumbers;
    
            m_matchingNumbers = new std::set<int>();
            m_winningNumbers = new std::set<int>();
    
            if( m_matchingNumbers && m_winningNumbers )
            {
                *m_matchingNumbers = rhs->m_matchingNumbers;
                *m_winningNumbers = rhs->m_winningNumbers;
            }
        }
        // more implementation...
    private:
        std::set<int> * m_matchingNumbers, 
                      * m_winningNumbers;
    };
    Last edited by whiteflags; 02-10-2008 at 07:41 PM.

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Am I doing something wrong, or is calling a constructor from another constructor not allowed?
    Delegating constructors are not possible in C++98. They will be in C++09, small consolation as that may be.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Thanks.
    Does anyone know if there was a logical reason why they decided that calling non-base constructors in initialization lists shouldn't be allowed?

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Because, if common code was required in two or more constructors, a member function could be defined and called by both constructors. Delegating constructors are therefore technically unnecessary, and were viewed as an unnecessary feature by the standard committee. The original proposal for delegating constructors also did not define what was required particularly well (the syntax was essentially what is put forward now, but the actual semantics were poorly defined). The combination of a technically unnecessary feature being the subject of a poorly defined technical proposal led to rejection.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    But a delegating constructor can be called from the initializer list, whereas a member function could not. So technically there is a difference, right?

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    More importantly, a delegated-to constructor can have an initializer list of its own, whereas a member function cannot.
    Which is why the feature will be there in 09.
    I think the restriction is something like: the initializer list may contain a delegation to another constructor of the same class or a list of base and member initializers, but not both. This is necessary to ensure sane semantics.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I think the restriction is something like: the initializer list may contain a delegation to another constructor of the same class or a list of base and member initializers, but not both. This is necessary to ensure sane semantics.
    Sounds good. I kind of liked the constructor chaining thing in Java, though part of its added usefulness was due to the lack of default arguments as a language feature.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cpjust View Post
    I
    Code:
    	TicketComparator( const std::set<int>*  winningNumbers,
    				std::set<int>*  matchingNums )
    		:	m_WinningNumbers( winningNumbers ),
    			m_MatchingNums( matchingNums ) {}
    
    	TicketComparator( TicketComparator&  rhs )
    		:	TicketComparator( rhs.m_WinningNumbers, rhs.m_MatchingNums ) {}
    This copy constructor is unnecessary. The other constructor just copies values into member variables. The default copy constructor would do exactly the same thing.

  11. #11
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by brewbuck View Post
    This copy constructor is unnecessary. The other constructor just copies values into member variables. The default copy constructor would do exactly the same thing.
    Yeah, I guess you're right. I made a lot of changes to the class, so I'm not sure if I needed it before or not, but I sure don't now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 06-10-2008, 08:38 PM
  2. C++ have a constructor call another constructor
    By QuestionC in forum C++ Programming
    Replies: 4
    Last Post: 05-17-2007, 01:59 AM
  3. Replies: 3
    Last Post: 03-26-2006, 12:59 AM
  4. How do I override constructor in inheritance?
    By Loduwijk in forum C++ Programming
    Replies: 13
    Last Post: 03-24-2006, 09:36 AM
  5. Need help in classes
    By LBY in forum C++ Programming
    Replies: 11
    Last Post: 11-26-2004, 04:50 AM