Calling the constructor of the base class after so

2019-01-25 05:26发布

As far as I know it is not possible to call the constructor of the base class. The only way I know is this:

MyClass::MyClass(/* args */) : Base(/* args */)
{
   // ...
}

but this would invoke the constructor at the beginning. Is there any way to call it somewhere else in the constructor? Something like this:

MyClass::MyClass(/* args */)
{
   // ... instructions
   Base::Base(/* args */);
   // ... other_instructions
}

According to this What are the rules for calling the superclass constructor? question I understand there is no way but I read here and I guessed it was possible, but if I try I get:

error: invalid use of 'class Base'.

Am I doing something wrong? Is it possible to do this some way or is there any other possible solution to this need?

Thanks!

EDIT: I understand I forgot a key point: the base class is part of a framework, and therefore it would be good not to have to modify it, if possible.

标签: c++ oop class
7条回答
虎瘦雄心在
2楼-- · 2019-01-25 05:38

The base class is always fully constructed before construction of your own class begins. If you need to make a change to the state of the base class, you have to do that explicitly after it has been constructed.

Example:

MyClass::MyClass()
{
    // Implicit call to Base::Base()

    int result = computeSomething();
    Base::setResult(result);

    // ... 
}
查看更多
萌系小妹纸
3楼-- · 2019-01-25 05:44

No, you can't do it that way, as other have described in their previous answers.

Your only chance is composition, IOW that MyClass uses Base class as a member field:

class MyClass {
public:
   /** the methods... */

private:
   Base* _base;
};

so you can initialize _base later, when you have the needed info. I don't know if this can apply to your scenario, anyway.

查看更多
Lonely孤独者°
4楼-- · 2019-01-25 05:50

Besides the already written solutions, you can also use a static constructor function and make the contructor of MyClass private.

class QtBase{
  // ...
};

class MyClass : public QtBase{
public:
  // copy ctor public
  MyClass(MyClass const& other);

  static MyClass Create(/*args*/){
    // do what needs to be done
    int idata;
    float fdata;
    // work with idata and fdata as if they were members of MyClass
    return MyClass(idata,fdata); // finally make them members
  }

  static MyClass* New(/*args*/){
    int idata;
    float fdata;
    // work with idata and fdata as if they were members of MyClass
    return new MyClass(idata,fdata); // finally make them members
  }

private:
  // ctor private
  MyClass(int a_idata, float a_fdata)
    : idata(a_idata)
    , fdata(a_fdata)
  {}

  int idata;
  float fdata;
};

Now you would have to create instances of MyClass either as:

MyClass obj = MyClass::Create(/*args*/);

or

MyClass* ptr = MyClass::New(/*args*/);
查看更多
可以哭但决不认输i
5楼-- · 2019-01-25 05:52

no, because it will not be type safe.
consider you have: a class A and a variable A.var.
now consider B inherits from A, and uses var before A was initialized. you will get a run time error! the language wants to prevent this, thus superclass constructor must be initialized first.

查看更多
男人必须洒脱
6楼-- · 2019-01-25 05:55

No. It is not possible, because the order of constructor calls is strictly defined by the standard. Base class ctor has to be executed before the derive class ctor can be executed.

查看更多
爱情/是我丢掉的垃圾
7楼-- · 2019-01-25 06:00

Use the base-from-member idiom to run your code before the ctor of the "real" base class (which is Base):

struct Base {
  Base(string, int);
};

struct DerivedDetail {
  DerivedDetail() {
    value = compute_some_value();
    value += more();
    value += etc();
    other = even_more_code(value);
  }
  string value;
  int other;
};

struct Derived : private DerivedDetail, Base {
  Derived() : Base(value, other) {}
  // In particular, note you can still use this->value and just
  // ignore that it is from a base, yet this->value is still private
  // within Derived.
};

This works even if you don't have actual members you want in DerivedDetail. If you give more specifics on what you must do before the Base's ctor, then I can give a better example.

查看更多
登录 后发表回答