如何正确避免CS2512
请帮助我解决以下问题:
我有以下课程:
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++,所以我想了解它们。
Please help me with the following problem:
I have the following classes:
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);
};
The implementation is obvious. I intended to initialize the CombinationRule using the Init method to minimize code duplication. Alas, if I do not use "member initialization list" in each constructor the compiler complains with "error C2512: 'ChemicalElement' : no appropriate default constructor available". Is there an elegant way to solve this error instead of using a default constructor or member initialization list?
BTW: if there are any other problems in the classes definition please add it too. Since I'm revisiting C++ I want to be aware of them.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您应该按如下方式实现
CombinationRule
的构造函数,以便它们使用ChemicalElement
的适当构造函数:You should implement constructors of
CombinationRule
as follows so they will use appropriate constructors ofChemicalElement
:我认为如果您想在任何类型的数组或容器中使用该类的对象,则需要在定义任何其他构造函数的任何类中放置默认构造函数。不过,默认构造函数的实现可以只是一个空/无操作方法。
您不需要放入成员初始化列表(尽管在某些情况下使用成员初始化列表可能更有效,因为这样您的成员变量仅初始化一次,而不是通过默认构造函数初始化一次,然后由您的 Init() 方法第二次写入)
I think you are required to put a default constructor in any class where you define any other constructors, if you want to use objects of that class in any kind of array or container. The default constructor's implementation can just be an empty/no-op method though.
You shouldn't need to put in a member initialization list (although using a member initialization list can be more efficient in some cases, since that way your member variables are only initialized once, instead of being initialized once via their default constructor, and then written to a second time by your Init() method)
我想你想要这个,
我这么说是因为我认为它试图在你的 CombinationRule 上运行默认构造函数,进而需要获取 ce1 和 ce2 的 ChemicalElement ...但我可能是错的。
很确定 Krill 的方法是为特定构造函数指定变量的构造函数的方法,但我说了 f 那并且只是这样做了,所以 ce1 不需要由编译器构造:)
I think you want this
I say this because I think its trying to run the default constructor on your CombinationRule and in turn needs to get a ChemicalElement for ce1 and ce2 ... but I could be wrong.
Pretty sure Krill's way is the way to specify the constructor of a variable for a specific constructor BUT i said f that and just made it so ce1 doesn't need to be constructed by the compiler :)
在这个特定的示例中,我将继续进行重复(它只是编写两个初始化程序,没有什么值得痴迷的)。
但假设真实的情况更复杂:使用面向对象的工具来避免代码重复。
class CombinationRule : public ElementPair ...
或
class Combination { ElementPair TwoElements; ...}
其中 ElementPair 包含两个 ChemicalElements 和一个构造函数(具有公共代码),并且组合规则构造函数使用 ElementPair 的构造函数进行初始化。
还有其他方法:使用某些 InvalidChemicalElement 实例初始化成员或使用 InvalidChemicalElement 的 NULL 指针 (auto_ptr)。
In this particular example I would go on with duplication (it's just writing two initializers, nothing to get obsessive about).
But assuming the real story is more complex: use OO facilities to avoid code duplication.
class CombinationRule : public ElementPair ...
or
class Combination { ElementPair twoElements; ...}
Where ElementPair contains two ChemicalElements and a single constructor (with common code), and Combination rule constructors initialize using constructor of ElementPair.
There are other approaches: initializing members with some InvalidChemicalElement instance or using pointers (auto_ptr) with NULL for InvalidChemicalElement.