4

通常构造函数应该是这样的:

//ctor1
SmallSim::SmallSim()
:mSimInit(false)
,mServersCreated(false)
,mTotalCPUTime(0)
{
    ...
}

如果我有多个构造函数会怎样?

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

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

    ...
}

那么我需要在我拥有的每个构造函数上重复 :mSimInit(false) ,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;
}

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

4

4 回答 4

10

如果你这样做:

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

    ...
}

标有 1 的行创建了一个新的SmallSim临时对象,该对象很容易被销毁,因为它没有被使用。它对当前正在初始化的对象没有任何影响。要在同一个对象上调用另一个构造函数,你可以这样做:

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

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

于 2012-05-02T15:57:44.787 回答
6

C++03 中有两个选项:

  • 使用从每个 ctor 调用的 init 函数
  • 为所有 ctor 提供初始化列表

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

于 2012-05-02T15:56:34.313 回答
2

没有正确的方法来做到这一点。如果将初始化委托给函数,则默认初始化数据一次,然后分配值。如果您想从初始化列表构造中受益,那么您必须重复自己。偏好不同。

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

C++11 还允许在声明点进行初始化,这可能会有所帮助:

struct Foo {
  int i{0};
  double x{0.}:
};

在这里,构造函数不必对ior做任何事情x,除非他们想改变值。

于 2012-05-02T15:57:06.130 回答
0

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

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

抱歉,我没有很好地理解您的示例,我将使用一个简单的示例。假设有一家为旅行推销员准备的商务酒店,里面有一家自动化餐厅。

有一些机器接单,一些食物准备好了,如咖啡、面包或蛋糕、果汁,而其他食物如华夫饼、鸡蛋,则需要时间准备。

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

他可以稍后以相同的价格返回,以获取更多的任何东西。

这个例子将定义一个代表接受订单的机器的类。

请忽略次要语法、错误和错误,并检查这个想法以处理构造函数和字段初始化。


// 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
}

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

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

干杯。

于 2012-05-02T16:43:37.083 回答