4

我敢肯定,每个人都会不时面对丑陋的事情。

问题是向类添加一个字段并忘记扩展初始化列表,例如:

class T{
  private:
    field1;
    ...
    field10;
};

T::T( int speedValue ):
field1( Speed::MphToMps(speedValue) ),
field2( new OtherClass(14,5,15) ),
field3( PublicValueGenerator::generateNewFieldValue(0,15) ),
...,
field10( "unpredictable value" );

如果我匆忙添加一些字段,比如 newForgottenField,有时我会忘记设置初始化值。我记得有些 IDE 可以给出提示,但 vim+addons 是我的选择 :)

所以mb有一些提示可以简化跟踪这种情况或一些经验法则或粗鲁的宏,它们会给出警告或编译时错误(这将是惊人的:))?你如何克服这个障碍?

最好的祝福

4

4 回答 4

6

如果您使用的是 g++,那么它提供了一个选项,可以对违反 Scott Meyer 的有效 C++ 指南的构造发出警告:)
选项是:

-Weffc++ 

请注意,它还会启用许多其他警告。此外,并非所有标准库头文件都遵循 Meyers 准则。

于 2012-09-18T09:12:23.933 回答
1

获得所需内容的一种方法是确保所有字段都是类的实例,这些类要么具有执行所需操作的默认构造函数,要么仅具有需要参数的构造函数。

这并不总是很方便,但它肯定会解决您的问题。

于 2012-09-18T09:15:23.760 回答
0

这是一个很好的问题,能够轻松检查会很有用,但总的来说,C++ 可以实际支持的解决方案结合了易错性、冗长性和混淆性,这使得它们比您要解决的问题更加繁琐. 尽管如此 - 为了讨论起见 - 这里有一些方法......

您可以创建一个没有默认构造函数的类:

template <typename T>
class Explicitly_Initialised
{
  public:
    Explicitly_Initialised(const T& t) : t_(t) { }
    T& operator T() { return t_; }
    const T& operator T() const { return t_; }
  private:
    T t_;
};

或者,如果对象在被赋予值之前被读取,您可以有一个抛出的类(如果您有这样的概念,可能仅在“调试”构建中)。您可以决定 from 的值是否operator=正常。您需要一个bool has_been_initialised_;成员来跟踪它,在默认构造函数中设置为 false。一个麻烦是operator T()在写入之前不知道变量是否即将被读取,因此要完成一项彻底的工作,您可能需要一个代理对象来管理这种情况:痛苦。

或者,实际上推荐的太混乱了——您可能可以将一个接受类型列表的类组合在一起,为每种类型都有一个成员对象,并坚持在构造函数中使用匹配列表;让泛型类接受普通的任意标识符来访问数据成员是很困难的(如果类型是唯一的,则很容易允许数字访问,甚至是基于类型的访问)(您可能可以让它与宏黑客一起使用)。

于 2012-09-18T09:15:57.920 回答
0

在 C++11 中解决这个问题的最简单方法是为所有原始成员提供元素初始化器:

class T {
private:
    int field1{};
    ...
    int field10{};
};
于 2012-09-18T09:40:59.947 回答