Правильный способ наследовать шаблон класса от базового класса при специализации шаблона - PullRequest
0 голосов
/ 10 мая 2019

Я нахожусь в процессе разработки виртуального процессора и хочу представить регистры разных размеров, которые будет использовать виртуальный процессор.Я также хотел бы поместить их в один контейнер независимо от их фактических размеров и / или типов.

У меня была бы структура, которая выглядит так, чтобы хранить регистры

struct Memory {
    std::vector<std::shared_ptr<Register>> bank;
};

I 'Я пытаюсь создать базовый пустой класс как таковой:

struct Register {};

Теперь я буду наследовать от этого базового класса для создания различных типов поддерживаемых регистров.Эти регистры также зависят от нескольких typedefs ...

typedef std::int8_t   i8;
typedef std::int16_t i16;
typedef std::int32_t i32;
typedef std::int64_t i64;

typedef std::uint8_t   u8;
typedef std::uint16_t u16;
typedef std::uint32_t u32;
typedef std::uint64_t u64;

const u16 BYTE = 0x08, WORD = 0x10, DWORD = 0x20, QWORD = 0x40;

Допустим, я хочу иметь регистр, в котором его базовый тип данных - u8, другой - u16 и так далее ...

struct Register8 : Register {
    u8 value;
    u8 getValue() const { return value; }
};

struct Register16 : Register {
    u16 value;
    u8 getValue() const { return value; }
};

struct Register32 : Register {
    u32 value;
    u32 getValue() const { return value; }
};

struct Register64 : Register {
    u64 value;
    u64 getValue() const { return value; }
};

Так что это достаточно просто, однако мне не нравится тот факт, что я называю каждый из моих классов регистров по-разному, и я вижу некоторый дублирующий код, отличный от различий в типах, поэтому мы должны иметь возможность создаватьшаблон ...

struct Register{};

template<typename T>
Register_t : Register {
    T value;
    T getValue() const { return value; }
};

Это достаточно просто;Однако я хотел бы специализировать этот класс:

struct Register {};

template<typename T>
struct Register_t : Register {
    T value;
    T getValue() const { return value; }
};

template<>
struct Register_t<u8> {
    u8 value;
    u8 getValue() const { return value; }
};

template<>
struct Register_t<u16> {
    u16 value;
    u16 getValue() const { return value; }
};  

template<>
struct Register_t<u32> {
    u16 value;
    u16 getValue() const { return value; }
};

template<>
struct Register_t<u64> {
    u16 value;
    u16 getValue() const { return value; }
};  

Хорошо, это восходит к тому, что я говорил ранее о дублирующемся коде, и мы вводим больше, однако в моей ситуации это будут единственные приемлемые типы, когда-либо, поэтомубит дублирования не проблема.

Пока что все так хорошо ...

Теперь, скажем, я пытаюсь использовать это ...

main.cpp

#include <iostream>
#include "Register.h"

int main () {
    Register_t<u8> r8;
    r8.value = 8;
    Register_t<u16> r16;
    r16.value = 16;
    Register_t<u32> r32;
    r32.value = 32;
    Register_t<u64> r64; 
    r64.value = 64;

    Memory mem;
    mem.bank.push_back( std::make_shared<Register>( r8 ) );
    mem.bank.push_back( std::make_shared<Register>( r16 ) );
    mem.bank.push_back( std::make_shared<Register>( r32 ) );
    mem.bank.push_back( std::make_shared<Register>( r64 ) );

    return EXIT_SUCCESS;
};

Хорошо, я успешно сохранил их как общие указатели в векторе.Теперь возникает проблема или проблема ... Давайте попробуем получить доступ к этим значениям из класса

int main () {
    // ....

    for ( auto& b : mem.bank ) {
        std::cout << b->getValue() << '\n'; // Uh oh class Register has no member getValue() ...
    }

    return EXIT_SUCCESS;
}

Итак, вот моя проблема;Я не уверен, как косвенно вызвать функцию getValue() унаследованного класса или как правильно наследовать этот тип структуры проектирования - иерархию классов.Или, если я полностью исключу специализацию ... Это то, где я застрял, и любая помощь будет благодарна.

1 Ответ

0 голосов
/ 10 мая 2019

Я думаю, вам нужно что-то вроде этого:

struct Register {
    virtual int: getValue() = 0;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...