Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何初始化子类中的静态常量成员变量?_C++_Static_Constructor_Constants_Static Members - Fatal编程技术网

C++ 如何初始化子类中的静态常量成员变量?

C++ 如何初始化子类中的静态常量成员变量?,c++,static,constructor,constants,static-members,C++,Static,Constructor,Constants,Static Members,我正在尝试制作一个模板,它可以生成一些不同类型的类,这些类主要在名称上有所不同,例如,一个电阻器应该输出“电阻:4欧姆”,而电容器在同一个函数调用中输出“电容:4法拉”,而不会过载。理想情况下,单位应该是静态常量std::string值 我的方法是使基类未初始化 这里的问题是,现在我必须在所有子类中重载所有不同类型的构造函数 有没有办法初始化子类中的静态常量变量 谢谢CRTP可能会有所帮助: class CircuitElement { virtual const std::string

我正在尝试制作一个模板,它可以生成一些不同类型的类,这些类主要在名称上有所不同,例如,一个电阻器应该输出“电阻:4欧姆”,而电容器在同一个函数调用中输出“电容:4法拉”,而不会过载。理想情况下,单位应该是静态常量std::string值

我的方法是使基类未初始化

这里的问题是,现在我必须在所有子类中重载所有不同类型的构造函数

有没有办法初始化子类中的静态常量变量

谢谢

CRTP可能会有所帮助:

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");
类电路元件
{
虚拟常量std::string&getLabel()常量=0;
虚拟常量std::string&getUnit()常量=0;
};
模板
类CircuitElementBase:公共CircuitElement
{
公众:
常量std::string&getLabel()常量{return ElementType::Label;}
常量std::string&getUnit()常量{return ElementType::Unit;}
};
类别电阻器:公共电路元件基
{
静态标准::字符串标签,单位;
};
标准:串电阻:标签(“电阻:”);
标准:串电阻:单位(“欧姆”);

取决于您的要求,我想:

#include <string>
#include <iostream>
#include <sstream>

struct ResistorDescriptor
{
    static const std::string type;
    static const std::string unit;
};

const std::string ResistorDescriptor::type = "Resistance";
const std::string ResistorDescriptor::unit = "ohm";

struct CapacitorDescriptor
{
    static const std::string type;
    static const std::string unit;
};

const std::string CapacitorDescriptor::type = "Capacitance";
const std::string CapacitorDescriptor::unit = "farad";

template <class T>
class Element
{
public:
    Element(int val) : value(val) {}

    std::string output()
    {
        std::stringstream s;
        s << T::type << ": " << value << " " << T::unit << std::endl;
        return s.str();
    }

private:
    int value;
};

int main(int argc, char** argv)
{
    Element<ResistorDescriptor> resistor(4);
    Element<CapacitorDescriptor> capacitor(5);

    std::cout << resistor.output() << capacitor.output() << std::flush;

    return 0;
}

当前标准不允许在派生类构造函数中初始化基类的
public/protected
成员。我们必须依靠其他技术来实现它。有两种方法可以解决您的问题

(1) 声明
virtual
方法返回
std::string
以获得适当的标签/值。但是,这将导致不必要的开销。从您的实现中,我可以看出您想要避免它

(2) 使用一个中间的
模板
类,它将为您完成此任务

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> {
};
enum eValue{OHM,FARAD,AMP};//枚举到字符串映射
静态常量字符串值[]={“ohm”、“farad”、“amp”};
//将“value”作为引用字符串;避免复制多个副本
阶级基础{
Base(const string&v):值(v){}
public:const string&value;//必须使用对象访问
};
模板
struct Link:Base{//这是每个派生类的中间类
Link():Base(sValue[TYPE]){}
};
班级阻力:公共链接{
};

这正是我一直在寻找的答案——子类构造函数是否可以访问(继承的)基类公共成员。。谢谢
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> {
};