首页 > 解决方案 > 如何从实现接口的模板类实例访问结构

问题描述

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

#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;

我该如何解决这两个问题?

标签: c++c++11

解决方案


建议不要在同一篇文章中提出多个问题。

这使得给你一个简洁的答案变得更加困难。

对于你的第一个问题:

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

编译器会提醒您正在尝试编辑临时值。

为了使这项工作像编码一样,您需要更新 to 的签名T GetFields()T& GetFields()使其返回对内部字段的引用,而不是一个副本

对于你的第二个问题:

你不能像那样做多态性。接口不知道 aFields是什么。将 Fields 结构从 A 中拉出,以便一切都可以正确看到它,和/或使其成为模板参数的一部分。

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

在这种特定情况下,在 class 中指定的数据结构A具有 Type A::Fields,但Interface指定Interface::GetFields()返回类型不是Fields的对象的地址。A::Fields

为了使您当前的配置正常工作,您需要创建A::Fields一个派生自 的类Fields,并且如果您有另一个B定义特定Fields结构的类,则需要调用任何函数Interface::GetFields()来执行运行时类型自省 (RTTI),使用dynamic_casttypeid确定是否它在访问其成员之前有一个A::Fields或一个B::Fields先验,以避免读取数据结构的内存之外并触发分段错误。


推荐阅读