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

How to acess structure from an instance of templated class implementing an interface

本文关键字:实例 访问 结构 实现 接口      更新时间:2023-10-16

根据我的以下代码,我基本上有 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;

如何解决这两个问题?

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

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

对于您的第一个问题:

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

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

为了使此操作按编码方式工作,您需要将T GetFields()的签名更新为T& GetFields(),以使其返回对内部字段的引用,而不是副本

对于你的第二个问题:

你不能那样做多态性。界面不知道Fields是什么。将字段结构从 A 中拉出,以便所有内容都可以正确查看它,和/或使其成为模板参数的一部分。

更新:在评论中讨论内容时,您似乎正在尝试从内到外构建数据结构,而这不会编译。

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

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