0

请帮我解决以下问题:

我有以下课程:

class ChemicalElement
{
private:
    std::string _name;
    void Init(const std::string& name);
public:
    ChemicalElement(const std::string& name);
    ChemicalElement(const ChemicalElement& ce);
};

class CombinationRule
{
private:
    ChemicalElement _ce1;
    ChemicalElement _ce2;
    void Init(const ChemicalElement& ce1, const ChemicalElement& ce2);
public:
    CombinationRule(const ChemicalElement& ce1, const ChemicalElement& ce2);
    CombinationRule(const CombinationRule& rule);
};

实现是显而易见的。我打算使用 Init 方法初始化 CombinationRule 以最小化代码重复。唉,如果我不在每个构造函数中使用“成员初始化列表”,编译器会抱怨“错误 C2512:'ChemicalElement':没有适当的默认构造函数可用”。有没有一种优雅的方法来解决这个错误,而不是使用默认构造函数或成员初始化列表?顺便说一句:如果类定义中有任何其他问题,请也添加它。由于我正在重新访问 C++,因此我想了解它们。

4

4 回答 4

3

您应该实现CombinationRule如下构造函数,以便它们使用适当的构造函数ChemicalElement

CombinationRule::CombinationRule(const ChemicalElement& ce1, 
  const ChemicalElement& ce2) : _ce1(ce1), _ce2(ce2) 
{ 
  ... 
}

CombinationRule::CombinationRule(const CombinationRule& rule) : 
  _ce1( rule._ce1 ), _ce2( rule._ce2 )
{
  ...
}
于 2010-01-24T07:08:37.110 回答
1

如果您想在任何类型的数组或容器中使用该类的对象,我认为您需要在定义任何其他构造函数的任何类中放置一个默认构造函数。但是,默认构造函数的实现可以只是一个空/无操作方法。

您不需要放入成员初始化列表(尽管在某些情况下使用成员初始化列表可能更有效,因为这样您的成员变量只初始化一次,而不是通过其默认构造函数初始化一次,然后由您的 Init() 方法第二次写入)

于 2010-01-24T06:52:12.860 回答
1

我想你想要这个

ChemicalElement * ce1;

我这样说是因为我认为它试图在您的 CombinationRule 上运行默认构造函数,进而需要为 ce1 和 ce2 获取 ChemicalElement ...但我可能是错的。

很确定 Krill 的方式是为特定构造函数指定变量的构造函数的方式但是我说了 f 并且只是做了它所以 ce1 不需要由编译器构造:)

于 2010-01-24T07:12:56.370 回答
1

在这个特定的示例中,我将继续重复(它只是编写两个初始化程序,没有什么可着迷的)。

但假设真实情况更复杂:使用 OO 工具来避免代码重复。

class CombinationRule : public ElementPair ...

或者

class Combination { ElementPair twoElements; ...}

其中 ElementPair 包含两个 ChemicalElements 和一个构造函数(使用通用代码),组合规则构造函数使用 ElementPair 的构造函数进行初始化。

还有其他方法:使用一些 InvalidChemicalElement 实例初始化成员或使用 InvalidChemicalElement 为 NULL 的指针 (auto_ptr)。

于 2010-01-24T08:34:31.257 回答