Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从构造函数调用超类构造函数';身体_C++_Oop_Inheritance - Fatal编程技术网

C++ 从构造函数调用超类构造函数';身体

C++ 从构造函数调用超类构造函数';身体,c++,oop,inheritance,C++,Oop,Inheritance,我想创建一个类构造函数,它只在特定条件下调用它的超类构造函数。我当前的实现如下所示 class MyClass : public OtherClass { public: template<typename... Args> MyClass(bool condition, Args&&... args) { if(condition) { *(OtherClass*)this = Othe

我想创建一个类构造函数,它只在特定条件下调用它的超类构造函数。我当前的实现如下所示

class MyClass : public OtherClass
{
public:
    template<typename... Args>
    MyClass(bool condition, Args&&... args)
    {
        if(condition)
        {
            *(OtherClass*)this = OtherClass(args...);
        }
        else
        {
            //  Unrelated stuff
        }
    }
};

类MyClass:公共OtherClass
{
公众:
模板
MyClass(布尔条件、参数和参数)
{
如果(条件)
{
*(OtherClass*)this=OtherClass(args…);
}
其他的
{
//无关的东西
}
}
};
我不能在这里使用
MyClass(…):OtherClass(…){}
语法,因为不应该每次都调用超类的构造函数


有没有办法直接调用超类构造函数而不是调用移动构造函数(如我的示例所示)。

您可以为基类和派生类创建两个不同的构造函数。
派生类的构造函数调用基类的相应构造函数。
派生类中的静态方法根据传递的参数创建实例。
大概是这样的:

class OtherClass
{
  public:

    OtherClass()
    {
      ...
    }

    OtherClass(Args&... args)
    {
      ...
    }

} // class OtherClass

class MyClass: public OtherClass
{
  private:

    MyClass(): OtherClass()
    {
      ...
    }

    MyClass(Args&... args): OtherClass(args)
    {
      ...
    }

  public:

    static MyClass* createInstance(bool      condition,
                                   Args&&... args)
    {
      if (condition)
        return (new MyClass());
      else
        return (new MyClass(args));
    }

} // class MyClass

您可以为基类和派生类创建两个不同的构造函数。
派生类的构造函数调用基类的相应构造函数。
派生类中的静态方法根据传递的参数创建实例。
大概是这样的:

class OtherClass
{
  public:

    OtherClass()
    {
      ...
    }

    OtherClass(Args&... args)
    {
      ...
    }

} // class OtherClass

class MyClass: public OtherClass
{
  private:

    MyClass(): OtherClass()
    {
      ...
    }

    MyClass(Args&... args): OtherClass(args)
    {
      ...
    }

  public:

    static MyClass* createInstance(bool      condition,
                                   Args&&... args)
    {
      if (condition)
        return (new MyClass());
      else
        return (new MyClass(args));
    }

} // class MyClass

您可以通过以下方式重载构造函数以实现标记分派:

struct PassArgs{};
结构DoNotPassArgs{};
类MyClass:公共OtherClass{
公众:
模板
MyClass(PassArgs,Args&…Args):其他类(Args…{}
模板
MyClass(DoNotPassArgs、Args&&…):OtherClass(){}
};

您可以通过以下方式重载构造函数以实现标记分派:

struct PassArgs{};
结构DoNotPassArgs{};
类MyClass:公共OtherClass{
公众:
模板
MyClass(PassArgs,Args&…Args):其他类(Args…{}
模板
MyClass(DoNotPassArgs、Args&&…):OtherClass(){}
};

解决方案是不在构造函数中执行此操作,而是在助手函数中执行此操作。例如:

class BaseClass {
    BaseClass() {}
    BaseClass(int x) {setX(x);}
    void setX(int x) {
        //thing
    }
}

class Derived : BaseClass {
    Derived(int x) {
        if (x>10) setX(x);
    }
}

解决方案是不在构造函数中执行此操作,而是在助手函数中执行。例如:

class BaseClass {
    BaseClass() {}
    BaseClass(int x) {setX(x);}
    void setX(int x) {
        //thing
    }
}

class Derived : BaseClass {
    Derived(int x) {
        if (x>10) setX(x);
    }
}

罗伯特·科克的上述回答并不完全正确。他正在从派生类构造函数的初始化列表中调用基类(超级类)构造函数,但没有条件。但是根据您的问题
我们可以根据派生类构造函数体中的条件调用基类构造函数吗?
。答案是不,我们不能。根据面向对象原则,基类构造函数必须首先调用并初始化。在上面Robert Kock的回答中,在控件进入主体内部之前,在没有任何条件的情况下,从驱动类构造函数的初始化列表调用基类构造函数。在初始化列表中,您甚至不能设置任何条件。因此,从派生类构造函数的主体调用基于类的构造函数是不可能的。这就是我们在类中引入另一个名为init()的方法的原因。现在,下面的示例可以完全满足您的要求。在本例中,您必须在基类中添加一个默认构造函数,以便首先调用该默认构造函数,但在该默认构造函数中,您不会执行任何操作

现在请参见下面的示例:-

#include<iostream>

class B
{
  private:
  int x;
  int y;

  public:
  B(){std::cout<<"I am B's default constructor"<<std::endl;}//Default constructor not doing anything
  void init(int x)
  {
    std::cout<<"Based init with param x"<<std::endl;
    this->x = x; //this method initializing only one member
    y = 0;// just initialized with default value 0
  }
  void init(int x,int y)
  {
    std::cout<<"Based init with param x and y"<<std::endl;
    this->x = x; // here we initializing all the members
    this->y = y;
  }
  void print()
  {
    std::cout<<"x ="<<x<<std::endl;
    std::cout<<"y ="<<y<<std::endl;
  }
};

class D : public B
{
  public:
  D(int i)
  {
    std::cout<<"I am D's constructor"<<std::endl;
    if( i == 1 )
       B::init(3);
    else
       B::init(4, 5);
  }
};

int main()
{
   std::cout<<"First Example"<<std::endl;
   D *d = new D(1);
   d->print();
   std::cout<<"Now second Example"<<std::endl;
   D *d1 = new D(2);
   d1->print();
   return 0;
} 
#包括
B类
{
私人:
int x;
int-y;
公众:

上面罗伯特·科克的回答并不完全正确。他正在调用基类(superclass)派生类构造函数的初始化列表中的构造函数,但没有条件。但是根据您的问题
我们可以根据派生类构造函数体中的条件调用基类构造函数吗?
。答案是不,我们不能。根据面向对象原则,基类构造函数必须调用并初始化rst.在上面Robert Kock的回答中,在控件进入主体内部之前,基类构造函数是从驱动类构造函数的初始化列表中调用的,没有任何条件。在初始化列表中,您甚至不能放入任何条件。因此,不可能从派生的主体调用基类构造函数类构造函数。这就是我们引入另一个名为init()的方法来满足此类需求的原因在一个类中。下面的示例可以完全满足您的要求。在这个示例中,您必须在基类中添加一个默认构造函数,以便首先调用该默认构造函数,但在该默认构造函数中,您不需要执行任何操作

现在请参见下面的示例:-

#include<iostream>

class B
{
  private:
  int x;
  int y;

  public:
  B(){std::cout<<"I am B's default constructor"<<std::endl;}//Default constructor not doing anything
  void init(int x)
  {
    std::cout<<"Based init with param x"<<std::endl;
    this->x = x; //this method initializing only one member
    y = 0;// just initialized with default value 0
  }
  void init(int x,int y)
  {
    std::cout<<"Based init with param x and y"<<std::endl;
    this->x = x; // here we initializing all the members
    this->y = y;
  }
  void print()
  {
    std::cout<<"x ="<<x<<std::endl;
    std::cout<<"y ="<<y<<std::endl;
  }
};

class D : public B
{
  public:
  D(int i)
  {
    std::cout<<"I am D's constructor"<<std::endl;
    if( i == 1 )
       B::init(3);
    else
       B::init(4, 5);
  }
};

int main()
{
   std::cout<<"First Example"<<std::endl;
   D *d = new D(1);
   d->print();
   std::cout<<"Now second Example"<<std::endl;
   D *d1 = new D(2);
   d1->print();
   return 0;
} 
#包括
B类
{
私人:
int x;
int-y;
公众:

B(){std::coutBut超类的构造函数总是会被调用,但无论如何它都不会起作用。基类的构造函数必须在你进入子类的主体之前被调用。你到底想实现什么?听起来像是一个笨拙的设计,最好有两个构造函数来调用超构造函数具有不同参数的tor?
class MyClass:public OtherClass
表示“a
MyClass
是一个
OtherClass
”没有
OtherClass
就不可能有
MyClass
。条件是什么?如果在编译时可以知道它,您可能可以使用SFINAE执行此操作。但是超类的构造函数总是会被调用,而这是行不通的。在您甚至进入子类的主体之前,必须始终调用基类c'tor-类c'tor。你真正想实现什么?听起来像是一个笨拙的设计tbh,最好有两个构造函数用不同的参数调用超级构造函数?
class MyClass:public OtherClass
意味着“a
MyClass
是一个
OtherClass
”。没有
OtherClass