TITLE: Ron's member initialization idiom (Newsgroups: comp.lang.c++.moderated, 5 Feb 97) CALDWELL: Kelly Caldwell (tinkerkel@mindspring.com) > // How does one pass an object to the base class > // constructor without passing it as an argument > // to the derived class constructor? > // > // I'm trying to build a class which adds > // to the common dialog box FileOpenDialog. > // It works, except that the TData object > // is not being properly passed to the > // TFileOpenDialog constructor. > // The following are excerpts from the > // class definition and constructor. > // > // > class TImportDialog : public TFileOpenDialog > { > public: > TImportDialog(TWindow* pParent); > TFileOpenDialog::TData oFilenameData; > }; > // > // Constructor > // > TImportDialog::TImportDialog(TWindow* pParent) > : oFilenameData(OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST, > "All Files (*.*)|*.*|Text Files (*.txt)|*.txt|", > NULL, "c:\\", "*"), > TFileOpenDialog(pParent,oFilenameData,"Import"), > { > } KUEHL: kuehl@uzwil.informatik.uni-konstanz.de (Dietmar Kuehl) [snip] The reason is that the order of initialization is not determined by the order in which the members/bases appear in the initialization list but rather in the order in which they are declared. [snip] Thus, this would result in the base class 'TFileOpenDialog' to be constructed first followed by the 'oFilenameData' member. [snip] However, in your initializer list you write things as if they are order the other way around! A good compiler should issue a warning... (although this is not required to be standard conformant). A work-around to this problem is an idiom I use in the implementation of classes derived from the class '[io]stream' (where the derived classes do nothing except a more convenient interface to a class derived from 'streambuf'): You can use a private base class with the member which have to be constructed first. This is made the left most base class such that it is assured that this base is constructed first. I got this idea from Ron Klatchko which is why I generally call this idiom "Ron's member" (e.g. in comment explaining what is done). Here is an example of this idiom which should solve your problem: struct TImportDialog_pbase // Ron's member { TFileOpenDialog::TData oFilenameData; TImportDialog_pbase(): oFilenameData( OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, "All Files (*.*)|*.*|Text Files (*.txt)|*.txt|:, NULL, "c:\\", "*") { } }; class TImportDialog: private TImportDialog_pbase, public TFileOpenDialog { TImportDialog::TImportDialog(TWindow* pParent): TFileOpenDialog(pParent,oFilenameData,"Import") { } }; Since base classes are constructed in the order in which they appear in the class declaration (destruction is exactly reverse), the "member" 'oFilenameData' is constructed before the base class 'TFileOpenDialog'. [snip]