Question

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.

Was it helpful?

Solution

You should implement constructors of CombinationRule as follows so they will use appropriate constructors of ChemicalElement:

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

CombinationRule::CombinationRule(const CombinationRule& rule) : 
  _ce1( rule._ce1 ), _ce2( rule._ce2 )
{
  ...
}

OTHER TIPS

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)

I think you want this

ChemicalElement * ce1;

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 :)

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top