繁体   English   中英

C ++如何在派生类中实现const静态成员

[英]c++ how to implement const static members in derived classes

在C ++中,我有几个继承自抽象超类的类。 子类具有共享相同名称type的静态属性,但是当然具有不同的值。 我的问题是实现此目标的最佳方法是什么,每种实现的利弊是什么?

PS:这里有一些相关的讨论但是大多数都没有解释为什么不应该使用下面的方法(对我的机器有效)1。 此外,方法2中的子类方法不是静态的,因此我们将不得不获取实例来调用它们。

方法1:超类中的uinitialized const static

class Abstract {
  public:
    const static int type;
};

class C1: public Abstract {
  public:
    const static int type = 1;
};

class C2 : public Abstract {
  public:
    const static int type = 2;
};

方法2:使用虚拟函数代替变量

class Abstract {
  public:
    virtual int get_type() = 0;
};

class C1: public Abstract {
  public:
    int get_type() {return 1;}
};

class C2 : public Abstract {
  public:
    int get_type() {return 2;}
};

我不知道的其他方法...

编辑:

正如下面提到的一些答案/评论,我试图在运行时识别实际类型。 但是我真的不能想到更好的设计。

Abstract=EduInstAbstract=EduInst是教育机构的Abstract=EduInstC1=UnivC2=College等。我有一个std::map<Key, EduInst*>存储所有机构,这些机构是在运行时根据用户输入生成的。 有时我只需要在UnivCollege上进行操作。 什么是实现此目标的好方法?

首先警告:

继承描述了与基类的“某种”关系。 仅当您将不同种类的对象存储在同一容器中,这些种类的对象绝对共享相同的接口,并且不需要对任何派生类进行任何特殊处理时(例如,当您是对象的使用者时),这才有意义不需要知道其类型)。

此外,如果您只有几种相同的事物,并且在编译时就可以知道这些事物,那么使用继承可能是一个错误。

如果您的继承对象必须向客户端标识其实际类型,则这进一步证明了继承是错误的解决方案-因为现在您将使用代码来查找代码,这是一个坏主意(不可测试,并且有责任)程序处于意想不到的状态时会出错)。

此外,如果您有不同的对象但需要存储在同一容器中,则boost::variant可能是您正在寻找的解决方案。 然后,您可以使用boost::static_visitor对变量中的对象执行操作。 这样做的好处是绝对是类型安全的,并且编译器不会让您忘记处理类型。

说了这么多...

方法1无效,因为如果您已经具有派生类的类型,则将始终获得基类的类型。

方法2可以使用,但是很可怕,并且表明设计已损坏。

您不能有“虚拟”静态成员。

方法一是查找类的“类型”属性,第二种方法是查找实例的“类型”属性。
换句话说:使用第一个,您需要了解该类; 要使用第二个,您需要知道实例。
在您都不知道的地方编写代码是不可能的。

请注意,如果您在基类的函数中使用type ,则一种方法可能会给您带来意想不到的结果。
例如,

class Abstract
{
public:
    int get_type() const { return type; }
};

// ...
C1 c;
std::cout << c.get_type(); 

将输出0,因为那是Abstract::type的值。

第二种方法的一种变体是如果您牺牲了另一个成员的空间,则可以避免使用虚函数:

class Abstract {
  public:
    // ...
    int get_type() const { return type; }
  protected:
    Abstract(int t) : type(t) {}
  private:
    int type;
};

class C1: public Abstract {
  public:
    C1() : Abstract(1) {}
};

class C2 : public Abstract {
  public:
    C2() : Abstract(2) {}
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM