Как получить доступ к структуре из экземпляра шаблонного класса, реализующего интерфейс - PullRequest
0 голосов
/ 18 октября 2018

У меня в основном есть 2 вопроса на основе моего кода ниже:

#include <iostream>
#include <memory>

class Interface
{
public:
    virtual ~Interface() = default;
    virtual int GetOperation() const = 0;
};

template <typename T>
class Util : public Interface
{
   public:
    Util ();
    virtual ~Util (){}
    virtual int GetOperation() const override;
    T GetFields() ;
   private:
    int index;
    int operation;
    T mfield;
};

class A 
{
   public:
    A(){}
    int noOfPkts;
};
template <class T>
Util<T>::Util()
{
}

template <class T>
int Util<T>::GetOperation() const
{
    return operation;
}
template <class T>
T Util<T>::GetFields() 
{
    return mfield;
}


int main()
{
auto sn = std::make_unique <Util<A>>();
//sn->GetFields().noOfPkts = 10;
}

Если я раскомментирую код, я получаю ошибку компиляции:

$ c++ -std=c++14 try51.cpp
try51.cpp: In function 'int main()':
try51.cpp:51:26: error: using temporary as lvalue [-fpermissive]
 sn->GetFields().noOfPkts = 10;

Во-вторых, я действительно хочу реализовать винтерфейс метод, который будет возвращать структуру полей класса шаблона, как:

#include <iostream>
#include <memory>

class Interface
{
public:
    virtual ~Interface() = default;
    virtual int GetOperation() const = 0;
    virtual struct Fields* GetFields() const = 0;
};

template <typename T>
class Util : public Interface
{
   public:
    Util ();
    virtual ~Util (){}
    virtual int GetOperation() const override;
    virtual struct Fields* GetFields() const override;
   private:
    int index;
    int operation;
    T mfield;
};

class A 
{
   public:
    A(){}
    struct Fields {
        int noOfPkts;
        } f;
};
template <class T>
Util<T>::Util()
{
}

template <class T>
int Util<T>::GetOperation() const
{
    return operation;
}
template <class T>
struct Fields* Util<T>::GetFields() const
{
    return &mfield.f;
}


int main()
{
auto sn = std::make_unique <Util<A>>();
//sn->GetFields().noOfPkts = 10;
}

Но я получаю ниже ошибки компиляции -

$ c++ -std=c++14 try51.cpp
try51.cpp: In instantiation of 'Fields* Util<T>::GetFields() const [with T = A]':
try51.cpp:55:1:   required from here
try51.cpp:47:17: error: cannot convert 'const A::Fields*' to 'Fields*' in return
  return &mfield.f;

Как я могу исправить обе проблемы?

1 Ответ

0 голосов
/ 18 октября 2018

Рекомендуется не задавать несколько вопросов в одном посте.

Сложно дать вам краткий ответ.

На ваш первый вопрос:

Возвращение T GetFields() является временной копией внутреннего члена mfield.

Компилятор предупреждает вас, что вы пытаетесь редактировать временное значение.

В порядкечтобы сделать эту работу закодированной, вам нужно обновить сигнатуру T GetFields() до T& GetFields(), чтобы она возвращала ссылку во внутреннее поле вместо copy .

На ваш второй вопрос:

Вы не можете сделать полиморфизм подобным образом.Интерфейс не знает, что такое Fields.Вытяните структуру Fields из A, чтобы все могли видеть ее правильно и / или сделать ее частью параметров шаблона.

Обновление: после обсуждения вещей в комментариях может показаться, что вы пытаетесь спроектировать свои данныеструктуры наизнанку, и это просто не скомпилируется.

В этом конкретном случае структура данных, указанная в классе A, имеет тип A::Fields, но Interface указывает, что Interface::GetFields() возвращаетадрес объекта типа Fields, для которого A::Fields не является.

Для того, чтобы ваша текущая конфигурация работала, вам нужно будет сделать A::Fields классом, производным от Fields, и если выиметь другой класс B, который определяет конкретную структуру Fields, для выполнения любой функции, вызывающей Interface::GetFields(), потребуется выполнить самоанализ типа времени выполнения (RTTI), используя dynamic_cast или typeid, чтобы определить, имеет ли она A::Fieldsили B::Fields до доступа к его элементам, чтобы избежать чтения вне памяти структуры данных и не вызвать ошибку сегментации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...