简体   繁体   中英

How to pass a class's member object to its base class's constructor?

I want to make a class that passes a member object to its parent for initialization. The below code shows what I'm trying to do.

class TQueueViewerForm1 : public TQueueViewerForm
{
private:    // User declarations
  DOMMsgCollectionEditorImpl m_collection;
public:     // User declarations
  __fastcall TQueueViewerForm1(TComponent* Owner);
};

__fastcall TQueueViewerForm1::TQueueViewerForm1(TComponent* Owner)
  : TQueueViewerForm(Owner, m_collection)
{
}

This doesn't seem to work however. It looks like the constructor TQueueViewerForm() is being called before m_collection is initialized. This crashes the program since TQueueViewerForm() tries to use the uninitialized object.

So... what are my choices here? Ideally I would like to just initialize m_collection before the parent class is initialized somehow.

You have to remember the order of operations with inheritance. When you construct an instance of a class, first the base component gets constructed (ie your base class constructor gets run to completion); then, your class' members are initialized, and finally, your class' constructor gets run.

In this case, you're passing somewhat-random memory to your base class before it ever got initialized.

A derived class's parent constructor will always be called before the child's constructor. One option you have is to put the initialization code that you're trying to execute in a separate function in the parent class and call that function in the derived class's constructor.

class CollectionHolder {
public:
  DOMMsgCollectionEditorImpl m_collection;
};

class TQueueViewerForm1 :
  private CollectionHolder,  // important: must come first
  public TQueueViewerForm {
};

A bit too subtle for my taste. Personally, I'd try to find a design that doesn't require me to perform such gymnastics.

You can pass parameters to a base classes constructor using the initialization list of the derived classes constructor.

class Parent
{
public:
    Parent(std::string name)
    {
        _name = name;
    }

    std::string getName() const
    {
        return _name;
    }

private:
    std::string _name;
};

//
// Derived inherits from Parent
//
class Derived : public Parent
{
public:
    //
    // Pass name to the Parent constructor
    //
    Derived(std::string name) :
    Parent(name)
    {
    }
};

void main()
{
    Derived object("Derived");

    std::cout << object.getName() << std::endl; // Prints "Derived"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM