gpt4 book ai didi

c++ - header 中类的前向声明导致类型不完整

转载 作者:行者123 更新时间:2023-11-30 03:44:07 26 4
gpt4 key购买 nike

我看过forward declaring绕过编译错误“错误:变量或字段‘mov_avg’声明为无效”。
以下场景:有一个 data_proc.cpp 具有包含自定义 header 的 main() my_mov_avg.h,其中嵌入了函数 mov_avg(shared)。此外,头函数访问主文件中的 class cl_shared。文件如下所示:

#include <string.h>     //c++ headers
#include <iostream> //red?

#include "my_mov_avg.h" //outsourced function

using namespace std;

/* class accessed from header*/
class cl_shared {
public:
//constructor
cl_shared() { };

int getint() {
return a;
}
private:
int a;
};
cl_shared shared; //class object

/*main calling function inside header*/
int main(int argc, char **argv){
mov_avg(shared);
getchar();
return 0;
}

header my_mov_avg.h 文件:

//in .h
void say();
void mov_avg();

//in .cpp
#include <string.h>
#include <iostream>
#include "my_mov_avg.h"


void say() {
std::cout << "Ohai from another .cpp file!";
}
class cl_shared; //Forward declaration
void mov_avg(cl_shared shared){
std::cout<<" int from class: "<< shared.getint()<< std::endl;
}

现在,当我转发声明以便定义函数参数类型时,我得到了这个编译错误:

 error: ‘shared’ has incomplete type
void mov_avg(cl_shared shared){
^
/my_mov_avg.cpp:9:11: error: forward declaration of ‘class cl_shared’
class cl_shared;
^

如何让它编译,从 header 访问类 cl_shared 是不是糟糕的设计?
我试图实现的是从 header 的位置重复访问数据(这里分解为一个不断变化的 int) -函数被调用。
我可以将 class cl_shared 分解成一个单独的头文件并将其包含在两个头文件中,但我不确定,另外它会导致另一个头文件(可能不是必需的)。< br/>编辑 在 my_mov_avg.h 中添加了参数
void mov_avg(cl_shared shared); 但仍然会导致:

my_mov_avg.h:3:14: error: variable or field ‘mov_avg’ declared void
void mov_avg(cl_shared shared);

旁注:分解一个大的 cpp 文件的快速而肮脏的 hack 是将函数放入一个单独的 cpp 并将 #include "seperate.cpp" 放在函数最初所在的位置。仅用于简单程序。

最佳答案

仅当您将类用作指针/引用并且不尝试访问其任何成员时,前向声明才有效。当您按值传递时,编译器需要知道确切的大小等。类型的,因此需要完整的类声明。

void mov_avg(cl_shared shared){

此处您按值传递(即您在堆栈上传递 shared 的拷贝)因此编译器需要完整的类声明。此外,当您访问类的成员时,切换为通过指针/引用传递是不够的,因为编译器需要知道类成员的内存布局。

在使用之前,您需要在 my_mov_arg.h 可以访问它的地方声明 cl_shared。

当您在 header 中声明非类成员函数时,例如 mov_arg,您应该将它们声明为内联。否则函数定义将被添加到您使用头文件的每个源文件中并导致编译错误。

编辑。应该这样做。如果需要,您还可以将成员函数从 cl_shared.h 移动到 cl_shared.cpp 文件中。头文件顶部的#pragma once 用于确保每个编译单元只包含一次头文件:

cl_shared.h:

#pragma once

class cl_shared {
public:
//constructor
cl_shared() { };

int getint() {
return a;
}
private:
int a;
};

我的_mov_avg.h

#pragma once
#include "cl_shared.h"

void say();
void mov_avg(cl_shared shared);

关于c++ - header 中类的前向声明导致类型不完整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35688799/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com