В моем классе Instance существует проблема, заключающаяся в том, что я заметил разницу в поведении, связанную с двумя методами инициализации статического члена.
Шаблон класса Instance отслеживает уникальный счет.Уникальный счет используется для отслеживания количества производных классов для определенного типа.Он также используется для назначения уникального идентификатора / индекса для производных классов.
Первый инициализируется следующим образом:
template<typename Derived, typename Key>
Key Instance<Derived, Key>::count_static_assign{ std::numeric_limits<Key>::min() };
Второй инициализируется следующим образом:
template<typename Derived, typename Key>
Key Instance<Derived, Key>::count_default{ 0 };
Вывод программы
1 1
2 1
Я ожидаю, что два значения будут равны, потому что они оба должны увеличиваться.Однако count_static_assign
выдает неправильный вывод, так как кажется, что он сбрасывается и равен 1 дважды.Таким образом, я хотел бы знать, почему существует разница в поведении между этими двумя статическими переменными.
Вот файлы для программы, которая демонстрирует ошибку.
Instance.h
#ifndef INSTANCE_H
#define INSTANCE_H
#include <cinttypes>
#include <limits>
#include <iostream>
template<typename Derived, typename Key = std::uint16_t>
class Instance {
public:
using KeyType = Key;
static KeyType count_static_assign;
static KeyType count_default;
public:
Instance() = default;
virtual ~Instance() = default;
virtual KeyType getInstance() const = 0;
protected:
static KeyType generate() {
count_static_assign++;
count_default++;
std::cout << count_default << ' ' << count_static_assign << '\n';
return count_default;
}
};
//doesn't behave as expected
template<typename Derived, typename Key>
Key Instance<Derived, Key>::count_static_assign{ std::numeric_limits<Key>::min() };
//behaves as expected
template<typename Derived, typename Key>
Key Instance<Derived, Key>::count_default{ 0 };
#endif
Base.h
#ifndef BASE_H
#define BASE_H
#include <cinttypes>
#include <typeindex>
#include <memory>
#include "Instance.h"
class Base : public Instance<Base>
{
public:
Base(){}
~Base(){}
};
template<typename Derived>
class CRTPBase : public Base {
public:
static const KeyType STATIC_TYPE;
CRTPBase() {}
virtual ~CRTPBase() {}
virtual KeyType getInstance() const override {
return STATIC_TYPE;
}
};
template<typename Derived>
const typename CRTPBase<Derived>::KeyType CRTPBase<Derived>::STATIC_TYPE = CRTPBase<Derived>::generate();
#endif
Foo.h
#ifndef FOO_H
#define FOO_H
#include "Base.h"
struct Foo : public CRTPBase<Foo> {
Foo();
~Foo();
};
#endif
Foo.cpp
#include "Foo.h"
Foo::Foo()
{
}
Foo::~Foo()
{
}
Bar.h
#ifndef BAR_H
#define BAR_H
#include "Base.h"
struct Bar : public CRTPBase<Bar>
{
public:
Bar();
~Bar();
};
#endif
Bar.cpp
#include "Bar.h"
Bar::Bar()
{
}
Bar::~Bar()
{
}
main.cpp
#include "Foo.h"
#include "Bar.h"
int main() {
Foo foo;
Bar bar;
std::cin.get();
}
Если это имеет значение, я использую Visual Studio 2017 (Полная версия - 191426433 )Скомпилировать.Кроме того, режим отладки и выпуска не имеет значения.