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

问题描述 投票:0回答:1

我在类中有一个静态变量的问题。我正在尝试编辑子类的静态变量而不编辑其他子类静态变量。

头文件:

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() {}    
};

我正在尝试编辑我的类B的静态_name而不编辑我的类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;
};
c++ class inheritance casting static-variables
1个回答
1
投票

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

为避免在每个派生类型中重复相同的成员,您可以在位于A和派生类型BC之间的模板化中间类中定义它们。每个模板专业化都有自己的static成员。因此,如果每个派生类型为中间类型的模板参数提供唯一值,则它们将具有自己的名称。例如,将A拆分为两类:

#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
© www.soinside.com 2019 - 2024. All rights reserved.