尝试为所有子 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
我对 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