如何从实现接口的模板化类实例中访问结构

时间:2018-10-18 18:22:36

标签: c++ c++11

根据我的以下代码,我基本上有两个问题:

#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 :(得分:0)

建议不要在同一帖子中问多个问题。

给您一个简洁的答案要困难得多。

第一个问题:

返回T GetFields()是内部成员mfield的临时副本。

编译器会很有帮助地警告您,您正在尝试编辑临时值。

为了使编码工作正常,您需要将T GetFields()的签名更新为T& GetFields(),以使其返回对内部字段的 reference 副本

第二个问题:

您不能那样做多态。接口不知道Fields是什么。从A中拉出Fields结构,以便所有人都能正确看到它,并且/或者使其成为模板参数的一部分。

更新:在讨论注释中的内容后,您似乎正在尝试从内到外构建数据结构,而只是无法编译。

在这种特定情况下,类A中指定的数据结构的类型为A::Fields,但是Interface指定Interface::GetFields()返回类型为{的对象的地址。 {1}},其中Fields不是。

为了使当前配置正常工作,您需要将A::Fields设为派生自A::Fields的类,并且如果您还有另一个Fields类来定义特定的{{1} }结构,它将需要调用B的任何函数使用FieldsInterface::GetFields()来执行运行时类型自省(RTTI),以确定它是否具有dynamic_cast或{{ 1}},然后再访问其成员,以免读取数据结构的内存之外的内容并触发分段错误。