我正在设计库来为一台设备提供功能。该设备有一些共同的操作,但有不同的算法来完成这些操作。我想要一个函数原型(prototype)用于一个特定的操作,而不是一堆,而不是:
Alg1_Foo();
Alg2_Foo();
...
我想要这个:
Foo(alg);
但我不想将 alg 作为单独的参数传递,因为即使没有它,函数也会有很多参数,它们将有用于设备识别和/或授权的参数,in argument,out argument(至少其中之一),所以我认为将 alg 添加为单独的参数会很烦人。
所以我的想法是提供这样的解决方案:
Foo(const SomeUnion& some_union);
地点:
union SomeUnion {
AlgId alg_id;
alg1::SomeStruct alg1_some_struct;
alg2::SomeStruct alg2_some_struct;
SomeUnion(alg1::SomeStruct some_struct) { alg1_some_struct = some_struct; };
SomeUnion(alg2::SomeStruct some_struct) { alg2_some_struct = some_struct; };
};
特定算法的结构将是这样的:
namespace alg1 {
struct SomeStruct {
static const AlgId alg_id = ALG1;
. . .
};
}
所以如果想执行 alg1,我们将适当的结构传递给 Foo,它在 C++ 中工作,比如
alg1::SomeStruct a;
Foo(a);
但我希望我的库保持纯 C 的可能性。当然我需要:
删除引用并用指针替换它们;
删除命名空间(我们仍然可以借助结构来模拟它们(此线程可能对那些感兴趣的人有所帮助:Namespaces in C));
将定义结构的 C++ 风格替换为 C 中的结构,并在标签命名空间中定义名称 (typedef struct tagStruct {...} Struct;);
从内部结构和 union 中删除函数。
但是虽然我不明白是否有可能通过维护 C 来完成我想做的事情......你明白了吗?或者将 alg_id 作为单独的参数传递而不用担心 union 和结构(但我想尽可能避免它)是否更简单?
最佳答案
对我来说,这似乎是一个典型的案例,有人试图以“错误的方式”解决问题。
如果函数有“很多参数”,那么使用 struct
就可以了。但是在这样的 struct
中隐藏“你实际调用的函数”,然后在 union
中有多个 struct
的变体,现在我们试图在一个函数中塞入太多内容。开始拆分函数,使其只需要一个 struct
- 删除你的 union
作为参数 - 这是错误的。 [我曾使用过与此类似的代码 - 有可能偷偷加入一些做错事的代码并导致一些难以发现的错误,因为你将错误类型的 union
参数传递给了功能使这确实是一个糟糕的解决方案]。如果您将错误类型的结构传递给普通函数,那么编译器会告诉您。如果你填写了一个 union 的错误部分,使用结构“正确”部分的代码将得到“奇怪”的数据[很可能是未定义的行为] - 这种类型的错误可能很难找到。
所以是的,拆分你的功能,删除 union !
编辑:
如果您希望拥有一个简单且一致的界面,我想到的一个建议是您有一个工厂函数,您将 alg_id
传递给该函数,该函数返回一个指向相关函数的函数指针。不幸的是,如果每个函数的接口(interface)都像我建议的那样,是不同的结构,那么您仍然有可能将数据结构和函数混合在一起,但它确实减少了“已发布函数”的数量——事实上,这些函数根本不需要在提供它们的模块 [库甚至目标文件] 之外可见。
关于c++ - c\c++ - 以 union 作为参数以满足特定要求的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15168563/