我看了forward declaring以解决编译错误“错误:变量或字段'mov_avg'声明为void”。
以下场景:有一个data_proc.cpp具有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;
}
标题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;
^
如何让它编译,从头文件中访问类cl_shared是不好的设计?
我试图实现的是重复访问数据(这里分解为更改int)功能被称为。
我可以将class cl_shared
分成单独的头文件并将其包含在两者中但我不确定,另外它会导致另一个头文件(可能没有必要)。
编辑在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文件的快速而肮脏的黑客是将函数放入单独的cpp并将#include "seperate.cpp"
放在函数最初的位置。仅用于简单的程序。
答案 0 :(得分:2)
前向声明仅在您将该类用作指针/引用且不尝试访问其任何成员时才有效。当您通过值传递时,编译器需要知道确切的大小.etc。该类型因此需要完整的类声明。
void mov_avg(cl_shared shared){
在这里,您传递的是值(即您正在传递堆栈上的共享副本),因此编译器需要完整的类声明。此外,当您访问类的成员时,切换到指针/引用传递是不够的,因为编译器需要知道类成员的内存布局。
你需要在某个地方声明cl_shared my_mov_arg.h可以在使用之前访问它。
在标题中声明非类成员函数(例如mov_arg)时,您应该将它们声明为内联。否则,函数定义将添加到您使用标头的每个源文件中,并导致编译错误。
EDIT。这应该做到这一点。如果需要,还可以将成员函数从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;
};
my_mov_avg.h
#pragma once
#include "cl_shared.h"
void say();
void mov_avg(cl_shared shared);
答案 1 :(得分:0)
如果头文件只有
void mov_avg();
然后这将是一个不同的函数 - 一个不带参数的函数。 C ++强类型函数 - 重载可以有不同的参数签名但名称相同。所以它已经看到了move_avg()
的声明,但没有声明move_avg(cl_shared shared)
。