You are here:

C++/constructors in c++

Advertisement


Question
Hello sir !why can not we inherit constructors in c++?
i have read so many books.but i can not understand.
can you please explain clearly?

Answer


Because that is the way C++ is, or rather was. A mechanism to allow constructors to be inherited has been added to the latest revision of ISO standard C++ - C++11, although I am not sure which, if any, compilers have implemented this feature yet. The table at:

   http://wiki.apache.org/stdcxx/C++0xCompilerSupport

shows none of the compilers it tracks have done so as yet (at least as of the date of the table's last update - it looks reasonably up to date given highest versions of compilers mentioned). [Note: C++0x was the working name for C++11 as it was hoped to get the standard out before 2010 - a missed target obviously!]

I should mention that being an expert in writing C++ does not give me a 100% understanding of or insight into all the reasons for C++ being the way it is, although I can make some reasonable guesses for those areas where there is not either an obvious clear and straight forward reason or a stated reason I have come across. For insight into the topic of C++ history I recommend reading "The Design and Evolution of C++" by Dr. Bjarne Stroustrup - the inventor of C++. Once you have read that you should have a better handle on why C++ is the way it is.

Looking at what appears to be the final proposal paper for the inheriting constructors feature, N2540 from 2008, and also a late proposal to remove the feature in 2011, N3258:

   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm
   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3258.html

it would appear that as with so many 'obvious' missing features from C++ that it may have been missing for technical reasons and the need for such a feature was low compared to the effort of working out a solution and potential problems and risks implementing such a solution. After all you can always provide a set of simple forwarding constructor declarations and definitions that pass arguments to the required base constructor. Remember that someone (or group of someones) have to think up and work through such features and solutions. Even then it may be that it proves difficult or impossible to implement in some or all compilers - a risk noted in the N3258 paper, especially if, as with this proposal, there is no reference/proof of concept implementation.

I would also think that originally (in the 1980's, 1990's) the lack of inheriting constructors was not a problem - at least not of any great urgency - and that there were more important features C++ lacked to design and implement at the time. However having stabilised the C++ language and library feature set with the ISO 1998 standard (and the follow up 2003 'bug fix' update) there has been time for people to think on such things.

Some potential reasons and possible areas of implementation complexity for not implementing inheriting constructors sooner could be:

   - it is not required by all cases. In fact it certainly does not apply in many inheritance situations:
      - if the derived class adds state that needs initialising
      - if the derived class requires different argument sets
         (e.g. requires less because some base constructor parameters are fixed for derived class case,
         or the derived class adds arguments for additional values that require initialisation)
   - if a derived class inherits from multiple bases then there may be no single unambiguous base constructor and even in
      unambiguous cases some bases would not obviously be initialised - possibly different bases depending on which base a
      particular constructor was a member of.
   - virtual member functions are used and the dynamic type information - including virtual function despatch and RTTI data -
      differs between base and derived class instances.
      Constructors are special member functions. One of the (if not _the_) behind-the-scenes actions they perform is to ensure
      that the virtual function despatch mechanism and RTTI data are properly initialised for an object (typically by ensuring
      the v-table pointer is correctly initialised). I would guess that a pre-C++11 implementation could easily just associate
      a class name with a v-table and set the v-table pointer appropriately. Hence a base class would get a v-table pointer
      pointing to the base class' v-table and the derived class one that pointed to the derived class' v-table. If constructing
      an object of the derived class calls an inherited base class constructor then something extra would presumably need to be
      done to ensure the behind-the-scenes actions were performed correctly for the derived rather than base class context.
   - how inherited constructors interact with explicitly and implicitly declared constructors of the derived class.
      [Remember that a class having no explicitly declared constructors has implicitly declared (and defined) default and copy
       (and in C++11 move) constructors added by the compiler etc.]

I re-iterate that the above are only my (educated) guesses that came to mind while formulating this answer.

If you read at least some of N2540 - especially the examples in the proposed standard wording for section 12.9 near the end of the paper, you will see that you have to ask for constructors to be inherited using a using declaration that specifies the base class from which to inherit constructors from. You might also like to note the number of cases where using the feature results in an ill formed program and other problems. It is also interesting to note the changes to the proposal over time listed in the Summary of Changes section as well as the number of (often small) changes to the existing standard wording to incorporate the feature. You will note that many of the possible problems I mention have been addressed - at least in part.

If you read the text of the section 12.9 wording you will notice that unlike other cases of inheriting member functions inheriting constructors requires the compiler to effectively write derived class constructors for us that forward to the 'inherited' base class constructor. From the C++11 ISO standard section 12.9 paragraph 8 (also similar text appears in N2540 after the "struct D2 : B1, B2 {" example):

   "An implicitly-defined inheriting constructor performs the set of initializations of the class
    that would be performed by a user-written inline constructor for that class with a mem-initializer-list
    whose only mem-initializer has a mem-initializer-id that names the base class denoted in the
    nested-name-specifier of the using-declaration and an expression-list as specified below, and where the
    compound-statement in its function body is empty (12.6.2)."

It also notes that if such an inline forwarding constructor would cause the program to be ill-formed then so does getting the compiler to do it for us using inheriting constructors.

The expressions in the base constructor 'call' expression-list are defined to be:

   "Each expression in the expression-list is of the form static_cast<T&&>(p) where p is the name of the
    corresponding constructor parameter and T is the declared type of p"

You will note the comment in the example following the paragraph in question:

   struct B1 {
     B1( int ) {}
   };

   struct B2 {
     B2( double ) {}
   };

   struct D1 : B1 {
     using B1::B1; // implicitly declares D1( int )
     int x;
   };

And from the text of paragraph 8 we can infer that the implicit definition of the implicit D1(int) provided by the compiler would be:

   D1( int p ) : B1(static_cast<int&&>(p)) {}

This is the "something extra" I mused would be required to ensure the derived class behind-the-scenes actions are properly executed. Note that && is also a new C++11 feature called an rvalue reference and allows using move rather than copy semantics for cases of temporary values and something called perfect forwarding. Explaining these is rather beyond the scope of your question but there are various writings on these topics out there in the Intertubes, for example:

   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html

I hope that my answer gives you some vague idea as to why inheriting constructors have not until recently been a C++ feature - sorry that in this case there seems to be no definitive "because of this, that and the other..." answer. Things - life, the universe, everything,... - are like that sometimes. Ho hum...  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.