c++ - Is there a way to pass different structs to a single class constructor
问题描述
I have my own FIFO class that works OK, but I'd like to extend its flexibility.
Right now, the data struct that goes in the FIFO is defined in the FIFO class, so every FIFO object has the same data struct.
It would be nice if every object could define its own FIFO struct and pass it to the FIFO class. The FIFO class shouldn't care what the structure looks like, it just queues and enqueues whatever struct got passed to the FIFO constructor. This is actually well beyond my current skill set, but I thought with a little help, maybe I could pull it off.
Here's a simple example of what I'm trying to do that I haven't been able to compile:
class FIFO
{
public:
FIFO(struct myStruct&, uint32_t depth)
{
std::array<myStruct, depth>;
}
};
struct struct1
{
double s1Var1;
uint32_t s1Var2;
};
struct struct2
{
bool s2Var1;
};
FIFO fifo1 = new FIFO(struct1, 16);
FIFO fifo2 = new FIFO(struc2, 8);
I get this error at the std::array<myStruct, depth>
line:
Error: non-type template argument is not a constant expression
And this error at FIFO fifo1 = new FIFO(struct1, 16)
:
Error: 'struct1' does not refer to a value
and the same error for struct2
at FIFO fifo2 = new FIFO(struct2, 8)
.
If the solution is straight forward, I'd appreciate any help. If there's some topic I need to read up on before I try this, I'd be happy if someone would point me at it.
Looking at the comments, maybe I should have been more complete. This is for an embedded systems with lots of external devices of dubious reliability (mostly RS232 and some I2C). The actual IO to the devices is non-blocking DMA or interrupts. So, if I have a GPS device that talks over a UART, the GPS driver knows what its FIFO structure should look like. The GPS driver instantiates a UART object and passes it the GPS struct. The UART object instantiates a FIFO object with (in this case) the GPS struct. The FIFO class has the usual FIFO methods: enqueue, dequeue, isFull, isEmpty, etc.
When the over-arching state machine (SM) needs something from the GPS like a position fix, it calls something like GPS1.getPostionFix() method. The GPS driver does something like uart.writeCommand(getFix) and eventually the return message winds up in the UART's FIFO. The next cycle through the state machine, the SM asks the GPS driver if there's a fix available. The GPS calls something like uart.readFifo() which returns the latest message in the FIFO or -1 if the FIFO is empty. The GPS driver defined the GPS struct in the first place so it can parse, process and provide the position fix to the SM. The UART driver doesn't know anything about the struct it's enqueueing or dequeuing which seem like decent encapsulation to me. If anyone is still reading, comments on this approach would also be greatly appreciated.
解决方案
Is there a way to pass different structs to a single class constructor
No, it isn't possible to pass a type as a function argument (and constructors are (special member-) functions).
However, it is possible to pass types as template arguments, and a constructor can be an instance of a function template... Or the class itself can be instance of a class template. For example:
template<class T, std::size_t depth>
struct Fifo
{
Fifo()
{
std::array<T, depth> local_variable;
}
};
Fifo<struct1, 16> fifo1;
Fifo<struct2, 8 > fifo2;
std::array
itself is such a class template.
P.S. Avoid using all uppercase names for types (excluding single upper case charcter names which are conventional for template variables). Those names are conventionally reserved for macros.
P.P.S Avoid owning bare pointers. Avoid unnecessary dynamic allocation altogether.
推荐阅读
- button - 如何使用 javafx 更改网格窗格中所有项目的样式?
- esxi - esxi 无法创建内存不足的 vSwitch
- c# - 如何在 ASP.NET Core 2.x 中存储和检索处于 Session 状态的对象?
- c# - Xunit - 检查方法列表的返回值
- git - 一个分支的 git 合并受影响/与非相关分支的更改冲突
- python - ValueError:无法将字符串转换为浮点数:读取 csv 数据时“无”
- linux - 查找特定日期的文件并打开它
- excel - 将工作簿中特定工作表中的内容复制到同一目录中另一个工作簿中的另一个特定工作表
- richfaces - Maven 找不到库 com.sun.errorhandler.exceptionhandler
- c - Nginx 模块编写:如何将请求转发到服务器?