请帮我解决以下问题:
我有以下课程:
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 ++,我想要了解它们。
答案 0 :(得分: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 )
{
...
}
答案 1 :(得分:1)
我认为如果要在任何类型的数组或容器中使用该类的对象,我认为您需要在任何定义任何其他构造函数的类中放置默认构造函数。默认构造函数的实现可以只是一个空/无操作方法。
您不需要放入成员初始化列表(尽管在某些情况下使用成员初始化列表可能更有效,因为这样您的成员变量只初始化一次,而不是通过其默认构造函数初始化一次,然后通过Init()方法第二次写入)
答案 2 :(得分:1)
我想你想要这个
ChemicalElement * ce1;
我说这是因为我认为它试图在你的CombinationRule上运行默认构造函数,然后需要为ce1和ce2获取一个ChemicalElement ......但我可能错了。
非常肯定Krill的方式是为特定构造函数指定变量的构造函数的方式但是我说f并且只是因为ce1不需要由编译器构造:)
答案 3 :(得分:1)
在这个特定的例子中,我将继续复制(它只是编写两个初始化器,没有什么可以痴迷的)。
但假设真实的故事更复杂:使用OO工具来避免代码重复。
class CombinationRule : public ElementPair ...
或
class Combination { ElementPair twoElements; ...}
其中ElementPair包含两个ChemicalElements和一个构造函数(使用公共代码),而组合规则构造函数使用ElementPair的构造函数初始化。
还有其他方法:使用一些InvalidChemicalElement实例初始化成员或使用带有NULL的指针(auto_ptr)用于InvalidChemicalElement。