C++使用预定义结构体报SILO不完整类型错误 不调整定义位置如何解决
问题原因
你遇到的是C++不完整类型的标准限制:
- 前向声明(
struct SILO;)仅会告知编译器「SILO是一个结构体类型」,此时SILO属于不完整类型,仅支持定义对应的指针/引用参数,不允许访问其成员、创建值实例、计算类型大小 - 你原来的写法直接把MISSILE构造函数的实现写在了结构体内部,此时编译器还没有读到SILO的完整定义,不管你用值参数还是指针参数,只要访问
origin.Object就必然触发不完整类型错误
解决方案(无需调整SILO定义位置)
只需要把MISSILE构造函数的实现部分挪到SILO结构体定义之后即可,构造函数的声明仍然可以留在MISSILE结构体内部,完全不需要修改SILO的定义顺序。
修改后的代码示例:
// Vector2 is just a struct that represents a vector is 2D space. // 前向声明 struct SILO; struct ICBM; struct MISSILE; struct ICBM{ Vector2 launch; Vector2 target; Vector2 pos; int Velocity; ICBM(){ // Implementation not shown } void move(){ // implementation not shown } }; struct MISSILE{ Vector2 launch; Vector2 target; Vector2 pos; int Velocity; // 仅保留构造函数声明,不写实现 MISSILE(Vector2 t, SILO origin); // 如果要用指针版本,声明改为 MISSILE(Vector2 t, SILO* origin); 即可 void move(){ // implementation not shown } }; struct SILO{ Rectangle Object; // Rectangle has attributes x and y Vector2 pos; }; // SILO定义完成后,再实现MISSILE的构造函数 MISSILE::MISSILE(Vector2 t, SILO origin){ launch = (Vector2) {origin.Object.x, origin.Object.y}; target = t; pos = launch; Velocity = 10; } // 指针版本的构造函数实现参考: // MISSILE::MISSILE(Vector2 t, SILO* origin){ // launch = (Vector2) {origin->Object.x, origin->Object.y}; // target = t; // pos = launch; // Velocity = 10; // }
补充说明
值参数和指针参数都可以用该方案解决,区别仅在于值参数需要SILO的拷贝构造函数可用,指针参数不需要额外的拷贝开销。
内容的提问来源于stack exchange,提问作者a276me
相关产品推荐
相关产品推荐

