c - C中的OOP和结构的前向声明
问题描述
我正在学习 C 语言,最近学会了如何使用 C 编写 OOP。除了用于创建新类的结构类型的名称外,大部分内容对我来说并不难理解。
我的教科书用于struct dummy_t
前向声明typedef struct {...} dummy_t
及其定义。在我的理解中,这是两种不同的类型,因为前者是struct dummy
类型,而后者是struct
没有名称标签的类型,但教科书中的示例代码运行良好。
所以我特意修改了示例代码,以便结构名称的区别更加清晰。以下是我尝试过的代码行。
//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"
如您所见,我用于struct test_a
前向声明和typedef struct dummy {...} test_b
定义。我想知道为什么我没有得到编译错误并且它起作用了。
解决方案
我想知道为什么我没有收到编译错误
当您编译 main.c 时,编译器通过来自 class.h 的前向声明被告知有一个带有签名的函数struct test_a * test_init(void);
编译器只能相信它,即不会发出任何错误,也不会发出任何警告。
编译class.c
时没有前向声明,只有函数定义,即没有错误,没有警告。
将 .h 文件包含到相应的 .c 文件中总是一个好主意。如果您有一个#include "class.h"
in class.c,编译器将能够检测到不匹配。
..它奏效了
会发生什么:
指向 test_b 的指针被分配给指向 test_a 变量的指针
然后将该变量作为参数传递给期望指向 test_b 的指针的函数
因此,一旦您使用了指针,它就按照创建时的方式使用(即作为指向 test_b 的指针)。在两者之间,您只是存储在另一种指针类型的变量中。
那样行吗?不
在为另一种指针类型定义的对象中存储指向一种类型的指针是不行的。这是未定义的行为。在这种情况下,它“恰好起作用”。在现实生活中,它会在大多数系统上“碰巧工作”,因为大多数系统对所有类型都使用相同的指针布局。但根据 C 标准,这是未定义的行为。
推荐阅读
- ruby - Ruby - 获取本地文件的 UNC 路径
- r - 根据其他变量是否为“是”,使用“是/否”创建新变量。变异?
- visual-studio - @INC 中的 Win32/Process.pm 是什么?
- if-statement - 最大日期,基于不同的列
- python - 错误'numpy.float64'对象在应用函数后没有属性'shift'
- mysql - 错误 2002 (HY000): 无法连接到“192.168.1.15”上的 MySQL 服务器 (115)
- r - 寓言中的预测功能是否提供一步预测?
- c++ - 一个简单的 OOP 代码在 DEV-C++ 编译器中运行,但不在 VS 2019 中,为什么?
- python - google.cloud.vision_v1.types.image_annotator.AnnotateImageResponse 到 python 中的 Json
- android - 通过 ACTION_WIFI_ADD_NETWORKS 意图添加 WiFi 网络