【发布时间】:2020-02-26 02:23:44
【问题描述】:
在编写新的类函数时,我通常可以安全地将函数定义的第一行(从源文件中)复制到类头中以添加声明,使其成为类的一部分。我通常不使用 C++ 中的结构,但现在我遇到了这样一种情况,即在定义的参数列表中指定结构似乎有一些特殊情况。该结构是同一类的数据成员。
头文件中的函数定义:
int freq_sort(unsigned char* source, struct freq_pair* target);
源文件中该函数定义的第一行:
int TargaImage::freq_sort(unsigned char* source, struct freq_pair* target){
关于声明的编译器错误:
TargaImage.cpp:324:5: error: no declaration matches ‘int TargaImage::freq_sort(unsigned char*, TargaImage::freq_pair*)’
324 | int TargaImage::freq_sort(unsigned char* source, struct freq_pair* target){
| ^~~~~~~~~~
编译器错误提示正确的定义:
TargaImage.h:96:13: note: candidate is: ‘int TargaImage::freq_sort(unsigned char*, freq_pair*)’
96 | int freq_sort(unsigned char* source, struct freq_pair* target);
| ^~~~~~~~~
结构数据成员:
struct freq_pair {
unsigned char val;
int count;
};
我看到编译器看到的主要区别是范围解析运算符与定义中的 struct 参数一起使用,而不是声明。我不明白为什么会这样。这里发生了什么?
我尝试将类范围添加到定义、声明或两者中的 struct 参数,以哄骗它工作但无济于事。即使是这样,我也不明白问题是什么。
在此处查找问题的下一步是什么?
谢谢,
特伦特
编辑 1:
这是原始问题的最小可重现代码,从 cmets 获得的见解没有任何变化。
class TargaImage
{
public:
//function
int freq_sort(unsigned char* source, struct freq_pair* target);
//data member
struct freq_pair {
unsigned char val;
int count;
};
};
int TargaImage::freq_sort(unsigned char* source, struct freq_pair* target){
return 0;
}
int main(){
TargaImage obj;
return 0;
}
现在我明白了以与类类似的方式来考虑结构。因此,如果我本质上是在我的原始类中定义一个新的“类”(结构),那么包含该类以供使用的规则必须不同于通常的预处理器指令。我认为,由于新的 freq_pair“类”(结构)在原始 TargaImage 类中,因此它的定义在 TargaImage 成员函数的范围内。因此,从参数中删除 struct 关键字。但我得到了错误:
main.cpp:6:42: error: ‘freq_pair’ has not been declared
6 | int freq_sort(unsigned char* source, freq_pair* target);
|
所以我的结论是 freq_pair 超出了 TargaImage 的范围,尽管它是在类中定义的。这个结论正确吗?我应该如何通知 TargaImage::freq_sort(...) 类类型 freq_pair?
我认为将 C 风格的结构添加为数据成员是个好主意,但主要的收获可能是在其他地方定义一个类来保存该结构所持有的一对数据成员。
【问题讨论】:
-
该函数似乎不是结构/类的一部分,至少不是您所展示的。虽然你错过了很多 minimal reproducible example
-
结构在 C++ 中不是一个东西。
struct关键字只是声明类的另一种方式(C++ 类在许多方面恰好与 C 结构相似)。将关键字struct放在类名前面也是符合语法的,但这没有任何作用:它只是为了保持与 C 的兼容性。 -
"例如,如果没有它,我无法实例化一个新的结构局部变量" - 试试吧,你会感到惊讶 :-)
freq_pair my_local_instance; -
@hegel5000 C++ 中的
struct和class之间存在细微差别。在struct中,成员默认为public,在class中,默认为private。struct的默认继承关系是公共继承,class是私有继承。 -
@hegel5000 对于这个问题,意识到变量声明中的
struct可能也很重要确实做了一些事情:如果名称查找未找到该类型的声明,struct将(而不是失败)在变量声明的范围内声明一个新类。这可能是这里正在发生的事情,但在 OP 提供更多代码之前无法确定。