如何避免重写初始化列表中的构造逻辑?

时间:2013-02-01 01:30:51

标签: c++

假设我有一个像

这样的CPP类
 class A {
    A() :
     max_(0),
     num_(0),
     sum_(0),
     sum_squares_(0) {}

    void Clear() {
      min_ = bucketMapper.LastValue();
      max_ = 0;
      num_ = 0;
      sum_ = 0;
      sum_squares_ = 0;
    }

    void SomethingElse {}
}

我在构造函数和Clear中有初始化代码,有没有办法可以避免两次使用相同的代码。

2 个答案:

答案 0 :(得分:4)

如果需要多个调用相同逻辑的构造函数,则应在ClearReset函数中编写所有构造函数,并从每个构造函数中调用它。

初始化程序列表在相当少的情况下是必需的,除此之外,它只是效率的首选。

需要:

  • 基类(除非默认情况下没有参数构造函数,你可以调用它)
  • 作为参考的会员
  • const成员

答案 1 :(得分:2)

此原始代码,

 class A {
    A() :
     max_(0),
     num_(0),
     sum_(0),
     sum_squares_(0) {}

    void Clear() {
      min_ = bucketMapper.LastValue();
      max_ = 0;
      num_ = 0;
      sum_ = 0;
      sum_squares_ = 0;
    }

    void SomethingElse {}
}

由于缺少参数列表和分号而无法编译,并且无法在默认构造函数中初始化min_,使该成员保留不确定值,并且其中的所有内容都是的不可访问

你真的想在min_中给Clear一个不同的新值吗?

如果没有,那么只需分配一个默认构造的实例:

*this = A();

从构造函数中调用Clear通常不是一个好主意,主要是因为它非常类似于在赋值方面表达构造的不良习惯,因此可能会诱使你这样做。

对于更通用的解决方案,将纯数据分解出来:

namespace detail {
    struct A_Data
    {
        double min_;
        double max_;
        int    num_;
        double sum_;
    };
}  // namespace detail

class A
    : private detail::A_Data
{
public:    
    A(): detail::A_Data() {}

    void clear()
    {
        *this = A();
        min_ = bucketMapper.LastValue();
    }

    void somethingElse() {}
};

但很有可能

*this = A();

将作为满足您需求的解决方案。


-1表示不是真正的代码。请在以后的问题中发布实际代码。不一样。