Существует только один A::_name
, он может иметь только одно значение в любой момент времени. Поскольку все ваши производные типы используют один и тот же элемент static
, все они обязательно имеют одинаковое значение _name
. Чтобы исправить это, каждый производный тип должен предоставить свой собственный static
член.
Чтобы не повторять одни и те же члены в каждом производном типе, вы можете определить их в шаблонном промежуточном классе, который находится между A
и производными типами B
и C
. У каждой специализации шаблона есть свой 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