C语言:仅使用指针初始化结构体?

5
有没有一种方法可以确保在创建 struct 对象时它始终是一个指针?
例如:
typedef struct
{
  int foo;
} blah;

blah a; // error
blah* b; // ok

3
结构体永远不是指针,结构体就是结构体。指向结构体的指针是指针。如果您在此代码中让“b”指向某个东西,那么“*b”将需要成为一个“blah”,而不是指向“blah”的指针。 - user2357112
你实际上想要实现什么?为什么要禁止形式为 blah a; 的声明?你是想确保 blah 对象只能通过你提供的接口创建吗? - user2357112
我猜测你想防止结构体被分配到栈上。你能确认这是你的意图吗? - Holly
我希望我的结构体实例只能通过返回指针的函数创建,这样禁止在堆栈上创建实例对于紧凑性是有帮助的。 - Lemmons
2个回答

8
当然可以——你只需要把struct的定义放到一个单独的翻译单元中,远离公众视线。然后,在其他某个更公开的地方,只需声明该结构即可:
typedef struct x blah;

在这种情况下,blah 是一个不完整类型,因此只有访问该声明的人才能创建 blah * 对象,而无法创建完整的 blah 对象。
另一个选择是更改您的 typedef:
typedef struct
{
    int foo;
} *blah;

现在,blah 本质上是一个指针类型,任何声明:
blah b;

实际上只是创建了一个指针。由于这个struct本身是匿名的,除了通过仅限于指针的typedef之外,没有其他方法可以创建它。


2
+1 不完整类型 是解决 OP 问题的确切方法。 - R.. GitHub STOP HELPING ICE

0

苹果在其核心基础框架中经常使用这种语法。他们大量使用CF____Ref对象,就像这样:

struct __CFArray {
    // Internal Structure
};

// Copied from CFArray.h
typedef const struct __CFArray * CFArrayRef;

因此,如果您编写以下代码:

CFArrayRef myArray;

它自动成为一个指针。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接