您可以像这样在C中声明一个结构:
typedef struct MyStruct {
const char *name;
int (*func1)(void);
int (*func2)(void);
int (*func3)(void);
} MyStruct;
int test_func2(void) {
return 0;
}
MyStruct test_struct = {
.name = "buffer",
.func2 = test_func2,
};
这对于仅定义特定成员非常方便,所有其他成员都设置为0 / NULL。
编辑:特别是,这允许不知道如何定义MyStruct的细节,因此它可以在内部进行更改,添加新成员等。而不会破坏使用此类型的代码。
这不会用C ++编译器编译,但是会收到错误:
test.c:23: error: expected primary-expression before ‘.’ token
test.c:24: error: expected primary-expression before ‘.’ token
是否有相同的C ++声明实现相同的目标?
感谢。
编辑:@chris我可以告诉你不明白:) 而且很明显,大多数其他人评论我应该使用什么语法,结构应该如何定义等等。完全忽略了这一点。这与定义结构的正确方法无关,此片段仅用于提供上下文。至于代码等价, 在你的代码中的某处说:
MyStruct blah = { NULL, NULL, func2 };
现在MyStruct将其定义更改为:
typedef struct MyStruct {
const char *name;
int (*func4)(void);
int (*func1)(void);
int (*func2)(void);
int (*func3)(void);
} MyStruct;
你的代码仍然可以正常编译,但是引入了一个严重的回归:你现在可以初始化func1成员而不是像以前那样设置func2 ...
问题是关于C ++指定的初始化器是否相同:没有。问题已经结束。
答案 0 :(得分:15)
不,C ++不支持C99的指定初始值设定项。如果您想按名称设置个人成员,则需要通过分配来完成,例如
MyStruct test_struct = MyStruct();
test_struct.name = "buffer";
test_struct.func1 = test_func1;
答案 1 :(得分:2)
正如K-ballo所说,代码相当于:
MyStruct test_struct = {
"buffer",
test_func1
};
但是既然你正在使用C ++,你应该考虑为MyStruct编写和使用构造函数:
struct MyStruct {
const char *name;
int (*func1)(void);
int (*func2)(void);
int (*func3)(void);
MyStruct(const char *n,
int (*f1)(void) = NULL,
int (*f2)(void) = NULL,
int (*f3)(void) = NULL) : name(n), func1(f1), func2(f2), func3(f3) {}
};
请注意,在C ++中,您不需要将其定义为MyStruct,即使没有typedef,也可以使用MyStruct(不带struct关键字)。
答案 2 :(得分:2)
你可以使用lambda(从C ++ 11开始)。这将允许您保持声明不变,同时轻松初始化结构的全局/常量实例:
struct Test
{
int x;
float y;
};
const Test test=[]{ Test t{}; t.x=5, t.y=3.3465; return t; }();
#include <iostream>
int main()
{
std::cout << "test.x: " << test.x << ", test.y: " << test.y << "\n";
}
你甚至可以把它包装成一个宏,虽然在下面的表格中它只允许固定数量的初始化器:
// Macro to simplify it a bit
#define DECL_AND_INIT(Type,object,INIT1,INIT2) \
Type object=[]{ Type o{}; o.INIT1; o.INIT2; return o; }()
// Example usage
const DECL_AND_INIT(Test,test1,x=-7,y=-9.325e31);
请注意,您仍然必须在lambda中使用Test t{};
之类的值初始化 - 否则如果您初始化并非所有成员(例如由于添加了新成员),您将最终复制未初始化的变量,从而导致UB
答案 3 :(得分:1)
这个函数的等价是你struct
的一个空体的构造函数:
#ifdef __cplusplus
MyStruct::MyStruct(char* N, int (*F)(void)) :
name(N),
func1(0),
func2(0),
func3(F) {
// empty
}
#endif
(模拟一些语法错误,我的C ++有点生疏。)
这在功能上是等效的,因为它允许构造全局对象,即使它们具有const
限定字段,并且任何现代编译器都应该在编译时使用静态链接初始化对象。