Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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++;具有多个构造函数的init成员变量_C++ - Fatal编程技术网

C++ C++;具有多个构造函数的init成员变量

C++ C++;具有多个构造函数的init成员变量,c++,C++,通常,构造函数应如下所示: //ctor1 SmallSim::SmallSim() :mSimInit(false) ,mServersCreated(false) ,mTotalCPUTime(0) { ... } 如果我有多个构造函数会发生什么 在我看来,如果我从第二个构造函数调用第一个构造函数,那么第一个构造函数中的成员变量不会被初始化 //ctor2 SmallSim::SmallSim(bool ImmediateExecution, bool Report) {

通常,构造函数应如下所示:

//ctor1
SmallSim::SmallSim()
:mSimInit(false)
,mServersCreated(false)
,mTotalCPUTime(0)
{
    ...
}
如果我有多个构造函数会发生什么

在我看来,如果我从第二个构造函数调用第一个构造函数,那么第一个构造函数中的成员变量不会被初始化

//ctor2
SmallSim::SmallSim(bool ImmediateExecution, bool Report)
{
    SmallSim();

    ...
}
我需要重复一遍吗 :msimini(假) ,mServersCreated(false) ,mTotalCPUTime(0) 在我所有的构造函数上

据我所知,使用InitClassVars()并不是最好的方法

//ctor1
SmallSim::SmallSim()
{
    InitClassVars();

    ...
}

//ctor2
SmallSim::SmallSim(bool ImmediateExecution, bool Report)
{
    InitClassVars();

    ...
}

//Common function for init of member vars for multiple constructors
void SmallSim::InitClassVars(void)
{
    mSimInit = false;
    mServersCreated = false;
    mTotalCPUTime = 0;
}

是否有一种正确的方法来初始化成员变量而不在每个构造函数上重复初始化?

在C++03中有两个选项:

  • 使用一个init函数,从每个构造函数调用该函数
  • 为所有CTOR提供初始值设定项列表

在C++11中,您可以使用委托代理,以便从所有其他代理中调用一个代理。

没有正确的方法。如果将初始化委托给函数,则默认情况下会初始化数据一次,然后分配值。如果您想从初始化列表构造中获益,那么您必须重复自己的操作。偏好各不相同

幸运的是,C++11允许委托构造函数,请参阅

C++11还允许在声明时进行初始化,这可能有助于:

struct Foo {
  int i{0};
  double x{0.}:
};
在这里,构造函数不必对
i
x
做任何事情,除非他们想要更改值。

如果您这样做:

SmallSim::SmallSim(bool ImmediateExecution, bool Report)
{
    SmallSim(); // 1

    ...
}
标有1的行创建了一个新的
SmallSim
临时对象,由于未使用该对象,该对象很容易被销毁。它对当前正在初始化的对象没有任何影响。要对同一对象调用另一个构造函数,请执行以下操作:

SmallSim::SmallSim(bool ImmediateExecution, bool Report)
: SmallSim() {
    ...
}

(这是C++11的一个特性。)

正如@juanchopanza所提到的,处理构造函数没有“正确”或“完美”的方法,有几种方法可以分配对象并初始化其字段/属性

我不建议一个构造函数调用另一个构造函数,在同一个类上,它可能会一团糟

对不起,我不太理解你的例子,我将使用一个简单的例子。这家商务酒店为旅行推销员提供自动餐厅

有些机器可以点菜,有些食物已经准备好了,如咖啡、面包或蛋糕、果汁,而其他食物如华夫饼、鸡蛋则需要时间来准备

顾客可以到达餐厅,走到机器前,按一些按钮来点菜。在等待其他食物时,他(她)可能会要求提供一些已经准备好的食物,如咖啡。他也可以拿一个空盘子,等着一起上桌

他可以稍后回来,以同样的价格购买更多的东西

本例将定义一个类,该类表示接受订单的机器

请忽略一些小的语法、错误和bug,检查一下如何处理构造函数和字段初始化



请注意,所有这些函数,不是直接构造函数,而是像构造函数一样初始化字段,也称为“后构造函数”或“初始化器”

也可以将所有这些函数转换为真正的构造函数,但是,可能会有一些混乱,因此更容易,每个函数都有自己的标识符


干杯。

您使用的是C++03还是C++11?我使用gcc-std=C++0x进行编码,所以我认为是11,因为智能指针可以工作。添加从每个构造函数调用的init时,您必须小心。请确保此方法不是虚拟的,因为在构造函数中调用虚拟方法并不总是给出您期望的结果。@J_D:这当然是一个给定的要求,请参阅FAQ 23.5(尽管您可以在技术上使用虚拟方法,如果您非常非常小心,并且在特殊条件下)@很明显,你只需要初始化那个类中的变量,所以我不知道为什么你会期望一个虚拟函数在那里工作。我认为委托人就是答案。但现在我在说“输入'SmallSim'不是'SmallSim'的直接基础”时出错了,有什么想法吗?我的C++11标志处于打开状态…示例总是很有用的,谢谢,接受现在我收到一个错误,说“键入'SmallSim'不是'SmallSim'的直接基础”有什么想法吗?我的C++11标志处于启用状态…@可能您的编译器还不支持委托构造函数。好了,你至少需要GCC 4.7或Clang 3.0。@R.MartinhoFernandes就是这样!我在GCC4.6上,谢谢!
// note: good idea to add an empty value to enumerations:

enum BeveragesEnum {
  none,
  water,
  orangejuice,
  milk,
  coffe,
  cocoa
}; // enum BeveragesEnum

enum BreadsEnum {
  none,
  donut,
  bagel,
  cherrypie,
  applepie,
  cake
}; // enum BreadsEnum

enum FoodEnum {
  none,
  ScrambledEggs,
  OverEggs,
  Chicken,
  Waffles,
  Pancakes,
  Beef
}; // enum FoodEnum

class AutomatedCafeteriaClass
  protected: 
    BeveragesEnum Beverage;
    BreadsEnum Bread;
    FoodEnum Food;

    public:
      /* constructor*/ AutomatedCafeteriaClass();
      /* destructor*/ ~AutomatedCafeteriaClass();

    public:
      void quickGiveMeCoffe();
      void wantCoffeAndBread
        (
          BreadsEnum aBread
        );
      void onlyBeverage(BeveragesEnum aBeverage);
      void BeverageBreadFirstFoodLater
        (
          BeveragesEnum aBeverage;
          BreadsEnum aBread;
          FoodEnum aFood;
        );
      void waitForEverything
        (
          BeveragesEnum aBeverage;
          BreadsEnum aBread;
          FoodEnum aFood;
        );
      void wantFood
        (
          FoodEnum aFood;
        );

    public:
      void prepare();
}; // class AutomatedCafeteriaClass

/* constructor*/ AutomatedCafeteriaClass::AutomatedCafeteriaClass()
{
  // first assign empty values
  this.Beverage = BeveragesEnum.none;
  this.Bread    = BreadsEnum.none;
  this.Food     = FoodsEnum.none;
} // constructor AutomatedCafeteriaClass

/* destructor*/ AutomatedCafeteriaClass::~AutomatedCafeteriaClass()
{
  // clear by assigning empty values
  this.Beverage = BeveragesEnum.none;
  this.Bread    = BreadsEnum.none;
  this.Food     = FoodsEnum.none;
} // constructor AutomatedCafeteriaClass

void AutomatedCafeteriaClass::quickGiveMeCoffe()
{
  this.Beverage = BeveragesEnum.Coffe;
  prepare();
}

void AutomatedCafeteriaClass::wantCoffeAndBread
(
BreadsEnum aBread
)
{
  this.Beverage = BeveragesEnum.Coffe;
  this.Bread    = aBread;
  prepare();
}

void AutomatedCafeteriaClass::onlyBeverage(BeveragesEnum aBeverage)
{
  this.Beverage = aBeverage;
  prepare();
}

void AutomatedCafeteriaClass::BeverageBreadFirstFoodLater
(
BeveragesEnum aBeverage;
BreadsEnum aBread;
FoodEnum aFood;
)
{
  this.Beverage = aBeverage;
  this.Bread    = aBread;
  this.Food     = aFood;
  prepare();
}

void AutomatedCafeteriaClass::waitForEverything
(
  BeveragesEnum aBeverage;
  BreadsEnum aBread;
  FoodEnum aFood;
)
{
  this.Beverage = aBeverage;
  this.Bread    = aBread;
  this.Food     = aFood;
  prepare();
}

void AutomatedCafeteriaClass::wantFood
(
  FoodEnum aFood;
)
{
  this.Food     = aFood;
  prepare();
}

void AutomatedCafeteriaClass::prepare();
{
  // prepare the food
}