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

c++ how to implement const static members in derived classes

本文关键字:实现 const 静态成员 派生 c++      更新时间:2023-10-16

在C++中,我有几个从抽象超类继承的类。子类有一个静态属性,共享相同的名称type,但当然有不同的值。我的问题是,实现这一点的最佳方法是什么,每种实现的优缺点是什么。

PS:这里有一些相关的讨论,但大多数都没有解释为什么不应该使用下面的方法(在我的机器上工作)1。此外,方法2中的子类方法不是静态的,wwe必须获得一个实例才能调用它们。

Apporach 1:在超类中初始化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=EduInst代表教育机构,C1=UnivC2=College等。我有一个std::map<Key, EduInst*>存储所有机构,这些机构在运行时根据用户输入生成。有时我只需要在UnivCollege上操作。实现这一点的好方法是什么?

首先警告:

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

此外,如果只有几种相同的东西,并且这些东西在编译时可能是已知的,那么使用继承可能是错误的。

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

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

说了这么多。。。

方法1不起作用,因为如果您已经有派生类的类型,那么您总是会得到基类的类型。

方法2会起作用,但它很可怕,表明设计有缺陷。

不能有"虚拟"静态成员。

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

请注意,如果在基类的函数中使用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) {}
};