c++ - 如何从实现接口的模板类实例访问结构
问题描述
根据我的以下代码,我基本上有两个问题:
#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
。
编译器会提醒您正在尝试编辑临时值。
为了使这项工作像编码一样,您需要更新 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_cast
或typeid
确定是否它在访问其成员之前有一个A::Fields
或一个B::Fields
先验,以避免读取数据结构的内存之外并触发分段错误。
推荐阅读
- c# - C#.NET 中的 Pandas Dataframe 或类似内容
- javascript - 记住页面刷新后的日期
- vbscript - 带有相对引用的 VBScript 拖放
- javascript - 将订阅结果传递给 onNext
- javascript - 如何对数据进行分组?
- java - 导致错误描述的字符串请求正文数组:java.lang.NumberFormatException:对于输入字符串:“”
- maven - maven-surefire-plugin 无法加载我的 suiteXmlFile
- java - 为什么这段 Java 代码总是给我“错误”的声明?
- ruby - 为什么使用 ruby 查找具有所需文本的节点比使用 xpath 更快?
- ios - swift:表格视图删除错误的文件