尝试为所有子 class B 编辑父 A class 的静态变量

Trying to edit static variable of parent A class for all child class B

我对 class 中的静态变量有疑问。 我正在尝试编辑子 class 的静态变量而不编辑其他子 class 静态变量。

头文件:

class A {
public:
    A() {}

    void printName() {qDebug() << _name; }    
    void changeName(QString name) {_name = name;}

private:
    static QString _name;
};
QString A::_name = QString("default");

class B : public A {
public:
    B() : A() {}
};

class C : public A {
public:
    C() : A() {}    
};

我正在尝试编辑 class B 的静态 _name,而不编辑 class C 的 _name。当我在此 main.cpp 中尝试此代码时:

int main(int argc, char *argv[])
{
    A *a = new B{};
    A *b = new B{};
    A *c = new C{};

    a->printName();
    b->printName();
    c->printName();

    B *tmp = dynamic_cast<B*>(a);
    tmp->changeName("new");

    qDebug() << "Then";    

    a->printName();
    b->printName();
    c->printName();
}

这是我的:

"default"
"default"
"default"
Then
"new"
"new"
"new"

有人知道我该如何解决这个问题吗?

这是我也尝试过的方法:

class A {
    public:
    A() {}
    virtual ~A() {}

    void printName() {qDebug() << _name; }

    virtual void changeName(QString name) {_name = name;}
    private:
    static QString _name;
};

QString A::_name = QString("default");

class B : public A {
public:
    B() : A() {}

    void changeName(QString name) override {_name = name;}
private:
    static QString _name;
};

class C : public A {
public:
    C() : A() {}

    void changeName(QString name) override {_name = name;}
private:
    static QString _name;
};

只有一个A::_name,它在任何给定时间只能有一个值。由于所有派生类型都使用相同的 static 成员,因此它们必然都具有相同的 _name 值。要解决此问题,每个派生类型都必须提供自己的 static 成员。

为避免在每个派生类型中重复相同的成员,您可以在位于 A 和派生类型 B 和 [=19] 之间的模板化中间体 class 中定义它们=].每个模板专业化都有自己的 static 成员。因此,只要每个派生类型都为中间类型的模板参数提供唯一值,它们就会有自己的名称。例如,将 A 拆分为两个 classes :

#include <iostream>
#include <string>

class A {
public:
    virtual void printName() = 0;
    virtual void changeName(std::string name) = 0;
};

template<class T>
class A_impl : public A
{
public:
    void printName() override { 
        std::cout << _name << '\n';
    };
    void changeName(std::string name) override { 
        _name = std::move(name);
    };

private:
    static std::string _name;
};

template<class T>
std::string A_impl<T>::_name = "default";

那么每个派生类型应该继承自A_impl而不是A。通过向 A_impl 提供自己的类型,您可以确保每个派生类型都提供唯一的模板参数:

class B : public A_impl<B> { };

class C : public A_impl<C> { };

现在你的测试应该打印

default
default
default
Then
new
new
default