Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I initialize static constant member variables in a subclass?

I'm trying to make a template which can make a few different types of classes that differ mainly in the name of things, i.e. a resistor should output "Resistance: 4 ohm" where a capacitor would output "Capacitance: 4 farad" in the same function call, without overloading. Ideally the units would just be static const std::string values.

My method was to make the base class with uninitialized

Problem here is that now I have to overload all my different types of constructors in all the subclasses.

Is there a way to just initialize the static const variables in the subclass?

Thanks

like image 471
Alex Gosselin Avatar asked Jan 29 '26 23:01

Alex Gosselin


2 Answers

Initializing public/protected members of base class inside a derived class constructor is not allowed by current standard. One has to rely on other techniques to achieve it. There are 2 ways to address your problem.

(1) Declare virtual method returning std::string for appropriate label/values. However, this will cause unnecessary overhead. From your implementation I can make out that you want to avoid it.

(2) Use an intermediate template class, which will do it for you.

enum eValue { OHM, FARAD, AMP };  // enum to string mapping 
static const string sValue[] = { "ohm", "farad", "amp" };

// make the 'value' as reference string; to avoid making multiple copies
class Base {
  Base (const string &v) : value(v) {}
public:  const string &value; // has to be accessed using object
};

template<eValue TYPE>
struct Link : Base {  // this is an intermediate class for every derived
  Link () : Base(sValue[TYPE]) {}
};

class Resistance : public Link<OHM> {
};
like image 146
iammilind Avatar answered Feb 01 '26 12:02

iammilind


CRTP might be helpful:

class CircuitElement
{
    virtual const std::string& getLabel() const = 0;
    virtual const std::string& getUnit() const = 0;
};

template <typename ElementType>
class CircuitElementBase : public CircuitElement
{
public:
    const std::string& getLabel() const { return ElementType::Label; }
    const std::string& getUnit() const { return ElementType::Unit; }
};

class Resistor : public CircuitElementBase<Resistor>
{
    static std::string Label, Unit;
};

std::string Resistor::Label("Resistance: ");
std::string Resistor::Unit("ohm");
like image 26
Ben Voigt Avatar answered Feb 01 '26 13:02

Ben Voigt