C ++抽象类静态方法在派生类中显示

时间:2014-06-22 14:34:02

标签: c++ class inheritance static abstract-class

我来自C#背景,现在正试图拿起C ++。我使用一个具有静态成员的抽象类来跟踪该对象类型的总数,以及一个获取计数的静态方法。例如:

class Shape
{
public:
     virtual void Draw() = 0;
     static int GetShapeCount();
private:
     static int mShapeCount;
};

我注意到派生类也能够调用抽象类静态方法,我发现它有点好奇/令人困惑。例如,如果他们能够执行以下操作,可能会有人感到困惑:

Shape *newShape = new Rectangle();
cout << newShape->GetShapeCount();

这是否意味着获得矩形计数或形状计数?我还注意到即使你没有明确地将它称为形状,你仍然可以通过派生类访问静态方法:

Rectangle rectClass = Rectangle();
cout << rectClass.GetShapeCount();

所以我的问题是双重的:

1)为什么/如何可能这一点 2)有没有办法不允许派生类调用抽象类静态方法?

编辑:

我在C#中运行的测试是不正确的,它显示了类似的行为......我觉得静态方法也会落到派生类中似乎很奇怪。它与其他语言似乎一致,我想我只是犯了一个错误。

3 个答案:

答案 0 :(得分:3)

不,C ++没有多态静态函数,所以假设static getShapeCount()被实现为return mShapeCount;,它将返回基类值。但是,使用CRTP和静态多态可以很容易地模拟这一点。因为从对象而不是类本身调用静态函数不是一个好习惯,所以这就像魅力一样。

  

我还注意到,即使你没有明确地将它称为形状,你仍然可以通过派生类访问静态方法

您已宣布getShapeCount()是公开的,不是吗?而你(我想,再次,因为你没有向我们展示足够的代码)已经使用了公共继承。

答案 1 :(得分:2)

Shape *newShape = new Rectangle();
cout << newShape->GetShapeCount();

是一种写cout << Shape::GetShapeCount()的方式。

作为

Rectangle rectClass = Rectangle();
cout << rectClass.GetShapeCount();

是一种将cout << Rectangle::GetShapeCount()写成Shape::GetShapeCount()的方式。

如果您想禁止Rectangle::GetShapeCount() 你可以添加一个删除的功能(C ++ 11):

class Rectangle : public Shape
{
public:
// Previous methods

    static int GetShapeCount() = delete; // forbid the usage Rectangle::GetShapeCount()
};

答案 2 :(得分:1)

  

我注意到派生类也能够调用抽象类静态方法,我发现它有点好奇/令人困惑。

这与C#中的行为相同:派生类可以访问其基类的所有方法,只要它们的可见性(公共,受保护,内部等)允许它。

  

这是否意味着获得矩形计数或形状计数?

这是形状计数,因为所有派生类共享同一个计数器。

  

有没有办法不允许派生类调用抽象类静态方法?

是 - 您可以通过将方法设为private来隐藏派生类的方法。

如果您希望为每个派生类保留单独的对象计数,则可以创建静态map<type_index,int>,并递增特定类型的计数器。但是,您需要为static方法提供对调用者类型的访问权限。