子类化时覆盖静态变量

17 c++ inheritance static overriding

我有一个类,我们称之为A,在该类定义中我有以下内容:

static QPainterPath *path;
Run Code Online (Sandbox Code Playgroud)

也就是说,我正在声明一个指向路径对象的静态(类范围)指针; 此类的所有实例现在都具有相同的共享数据成员.我希望能够构建这个类,将其子类化为更专业的形式,分层行为,并且每个类都有自己唯一的路径对象(但不必像重复计算边界框或调用绘图例程那样重复).

如果我将它子类化为创建类F(例如),我希望F使用A中继承的绘图例程,但是要使用F中声明的静态(类范围)路径对象.我尝试过上面的声明私有部分(并在派生类F中重复它),并尝试在受保护的部分中使用它,一切都没有乐趣.

我可以理解为什么会这样:

void A::paint() {
    this->path...
Run Code Online (Sandbox Code Playgroud)

指的是A :: path而不是F :: path,即使对象属于F类.

是否有一种优雅的方法来绕过这个,并允许每个类维护一个静态路径对象,同时仍然使用基类中定义的绘图代码,并使所有类(可能除了基类)是真实的和可实例化的?

Joa*_*lva 17

使用虚方法获取对静态变量的引用.

class Base {
private:
    static A *a;
public:
    A* GetA() {
        return a;
    }
};

class Derived: public Base {
private:
    static B *b;
public:
    A* GetA() {
        return b;
    }
};
Run Code Online (Sandbox Code Playgroud)

请注意,B来自A.然后:

void Derived::paint() {
    this->GetA() ...
}
Run Code Online (Sandbox Code Playgroud)

  • 你说使用虚方法,但我没有在该代码中的任何地方看到关键字`virtual`.什么使该方法虚拟? (7认同)

Dav*_*nch 10

您可以在混合或奇怪的重复模板模式中执行变体

#include <stdio.h>

typedef const char QPainterPath;

class Base
{
public:
    virtual void paint() { printf( "test: %s\n", getPath() ); }
    virtual QPainterPath* getPath() = 0;
};

template <class TYPE>
class Holder : public Base
{
protected:
    static QPainterPath* path;
    virtual QPainterPath* getPath() { return path; }
};

class Data1 : public Holder<Data1>
{
};

class Data2 : public Holder<Data2>
{
};

template <> QPainterPath* Holder<Data1>::path = "Data1";
template <> QPainterPath* Holder<Data2>::path = "Data2";

int main( int argc, char* argv[] )
{
Base* data = new Data1;
data->paint();
delete data;

data = new Data2;
data->paint();
delete data;
}
Run Code Online (Sandbox Code Playgroud)

我刚刚在CodeBlocks中运行此代码并得到以下内容:

test: Data1
test: Data2

Process returned 0 (0x0)   execution time : 0.029 s
Press any key to continue.
Run Code Online (Sandbox Code Playgroud)


小智 8

我没有测试过这个,但是引入了一个虚函数:

struct Base {

    void paint() {
         APath * p = getPath();
         // do something with p
    }

    virtual APath * getPath() {
         return myPath;
    }

    static APath * myPath;
};

struct Derived : public Base  {

    APath * getPath() {
         return myPath;
    }
    static APath * myPath;
};
Run Code Online (Sandbox Code Playgroud)

可能是你想要的.请注意,您仍需要在某处定义两个静态:

APath * Base::myPath = 0;
APath * Derived::myPath = 0;
Run Code Online (Sandbox Code Playgroud)