[英]OOP and forward declaration of structure in C
I am studying C language and have recently learned how to write the OOP using C.我正在学习 C 语言,最近学习了如何使用 C 编写 OOP。 Most part of it was not hard that much to understand for me except the name of structures type used to create new class.
除了用于创建新 class 的结构类型的名称外,对我来说大部分内容并不难理解。
My textbook used struct dummy_t
for forward declaration and typedef struct {...} dummy_t
for its definition.我的教科书使用
struct dummy_t
进行前向声明,使用typedef struct {...} dummy_t
进行定义。 In my understanding, these are two different type because the former is struct dummy
type and the later is struct
type without a name tag but the sample code from the textbook worked well.在我的理解中,这是两种不同的类型,因为前者是
struct dummy
类型,而后者是没有名称标签的struct
类型,但教科书中的示例代码运行良好。
So I deliberately modified the sample code so that the difference in the names of structures will be much clearer.所以我特意修改了示例代码,以便结构名称的区别更加清晰。 Below are the lines of code I tried.
以下是我尝试过的代码行。
//class.h
struct test_a;
struct test_a * test_init(void);
void test_print(struct test_a*);
//class.c
#include <stdio.h>
#include <stdlib.h>
typedef struct dummy{
int x;
int y;
} test_b;
test_b * test_init(void){
test_b * temp = (test_b *) malloc(sizeof(test_b));
temp->x = 10;
temp->y = 11;
return temp;
}
void test_print(test_b* obj){
printf("x: %d, y: %d\n", obj->x, obj->y);
}
//main.c
#include "class.h"
int main(void){
struct test_a * obj;
obj = test_init();
test_print(obj);
return 0;
}
// It printed "x: 10, y: 10"
As you can see, I used struct test_a
for forward declaration and typedef struct dummy {...} test_b
for definition.如您所见,我使用
struct test_a
进行前向声明,使用typedef struct dummy {...} test_b
进行定义。 I am wondering why I did not get the compile error and it worked.我想知道为什么我没有得到编译错误并且它起作用了。
It 'worked' because you did not include class.h
in class.c
.它“有效”是因为您没有在
class.c
class.h
So the compiler can't see the implementation does not match the declaration.所以编译器看不到实现与声明不匹配。
The proper way is (but without the typedef for clarity):正确的方法是(但为了清楚起见没有 typedef):
// class.h
struct test_a;
struct test_a* test_init(void);
//class.c
#include "class.h"
struct test_a {
int x;
int y;
};
struct test_a* test_init(void)
{
...
}
The struct test_a
in the header file makes the name test_a
known to the compiler as being a struct. header 文件中的
struct test_a
使编译器知道名称test_a
是一个结构。 But as it does not now what is in the struct you can only use pointers to such a struct.但是由于它现在没有结构中的内容,因此您只能使用指向此类结构的指针。
The members are defined in the implementation file and can only be used there.成员在实现文件中定义,只能在那里使用。
If you want to use a typedef:如果你想使用 typedef:
// header
typedef struct test_a_struct test_a;
test_a* test_init(void);
//implementation
struct test_a_struct {
int x;
int y;
};
test_a* test_init(void)
{
...
}
I am wondering why I did not get the compile error
我想知道为什么我没有收到编译错误
When you compile main.c the compiler is told via a forward declaration from class.h that there is a function with the signature struct test_a * test_init(void);
当您编译 main.c 时,编译器通过来自 class.h 的前向声明被告知有一个 function 带有签名
struct test_a * test_init(void);
The compiler can't do anything other than just trusting that, ie no errors, no warnings can be issued.编译器只能相信它,即不会发出任何错误,也不会发出任何警告。
When you compile class.c
there is no forward declaration but only the function definition, ie no errors, no warnings.当您编译
class.c
时,没有前向声明,只有 function 定义,即没有错误,没有警告。
It's always a good idea to include the.h file into the corresponding.c file.将.h 文件包含到相应的.c 文件中总是一个好主意。 Had you had a
#include "class.h"
in class.c the compiler would have been able to detect the mismatch.如果您在 class.c 中有一个
#include "class.h"
,编译器将能够检测到不匹配。
..and it worked
..它奏效了
What happens is:会发生什么:
A pointer to test_b is assigned to a pointer to test_a variable指向 test_b 的指针被分配给指向 test_a 变量的指针
The variable is then passed as argument to a function expecting a pointer to test_b然后将该变量作为参数传递给 function 期望指向 test_b 的指针
So once you use the pointer it is used as it was created (ie as pointer to test_b).因此,一旦您使用了指针,它就按照创建时的方式使用(即作为指向 test_b 的指针)。 In between you just stored in a variable of another pointer type.
在两者之间,您只是存储在另一种指针类型的变量中。
Is that ok?那样行吗? No
不
Storing a pointer to one type in a object defined for another pointer type is not ok.在为另一种指针类型定义的 object 中存储指向一种类型的指针是不行的。 It's undefined behavior.
这是未定义的行为。 In this case it "just happened to work".
在这种情况下,它“恰好起作用”。 In real life it will "just happen to work" on most systems because most systems use the same pointer layout for all types.
在现实生活中,它会在大多数系统上“碰巧工作”,因为大多数系统对所有类型都使用相同的指针布局。 But according to the C standard it's undefined behavior.
但根据 C 标准,这是未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.