【问题标题】:Name followed by :: must be a class or namespace name名称后跟 :: 必须是类或命名空间名称
【发布时间】:2021-02-04 20:34:15
【问题描述】:

我在这里和互联网上的其他地方查看了许多关于此主题的文章,并开发了我的代码以符合我所学的内容。不幸的是,这似乎并不能解决这个问题。以下是拼图的部分:

定义的类:

class FileData {
private:
    char* filename;

public:
    FileData();
    void CloseFile(std::fstream file);
    int DeleteFile(char* fname);
    int FileExist(char* fname);
    int OpenDestFile(std::fstream file, char* fname);
    int OpenListFile(std::fstream file, char* fname);
    int OpenSourceFile(std::fstream file, char* fname);
    int ReadBuffer(std::fstream file, char* Buffer);
    int ReadListFile(std::fstream file);
    int WipeFile(char* fname);
    int WriteBuffer(std::fstream file, char* Buffer);
};

构造函数代码:

FileData::FileData() : filename(nullptr) {}

我遇到问题的已定义函数(与类的哪个函数无关......它们都有相同的错误):

int FileData::OpenListFile(std::fstream file, char* fname) {
    int ccode;

    ccode = 0;
    file.open(fname, std::fstream::in);
    if (file.bad()) {
        ccode = -1;
    }
    return ccode;
}

作为一个全局变量,我将 FileRec 声明为 FileData 的一个类:

FileData FileRec;

这是产生错误的实际函数调用:

if ((ccode = FileRec::OpenListFile(&ListFile, fspec3)) != 0) {
   // ....
}

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • OpenListFile 不将指针作为第一个参数。这里应该有几个错误。
  • 除非这些是static 方法,否则将它们称为X::Y() 是没有意义的。如果您有指针,您可以在 x 实例上调用它,例如 x.Y()x->Y()
  • 注意:在 C++ 中,使用std::string 通常是个好主意,而使用char* 来保留数据是个坏主意。内存管理并不容易,甚至不好玩。除非你 strdup() 你的论点你不能保证你可以保留它们,如果你复制,你必须在你的析构函数中释放,它没有显示,所以这可能是泄漏.
  • 提示:尝试为您的函数和变量名称选择一个命名约定。您同时使用Buffer(大写)和fname(小写)冷漠。在很多 C++ 代码库中,CapitalStyle 是为类保留的,其他的都是 lower_case 样式。
  • 好的。我在类中的每个函数定义(构造函数除外)中添加了“静态”,我有相同的结果吗?是的,我也修复了函数调用中的“&ListFile”问题(简单的错字)。至于使用的命名约定,这是一个旧的“C”程序,我正在转换为 C++(并同时学习)。

标签: c++ function class


【解决方案1】:

您已将 OpenListFile() 声明为 instance 方法,而不是 静态 方法。 FileRecinstanceFileData 类。您需要使用. 运算符来访问对象实例的成员,例如:

FileData FileRec;
std::fstream ListFile;
...
if ((ccode = FileRec.OpenListFile(ListFile, fspec3)) != 0) {
   // ...
}

否则,将static 用于不需要访问FileData 类的任何数据成员的任何方法,然后使用类名 而不是实例名 当使用:: 时,例如:

class FileData {
public:
    static void CloseFile(std::fstream file);
    static int DeleteFile(char* fname);
    static int FileExist(char* fname);
    static int OpenDestFile(std::fstream file, char* fname);
    static int OpenListFile(std::fstream file, char* fname);
    static int OpenSourceFile(std::fstream file, char* fname);
    static int ReadBuffer(std::fstream file, char* Buffer);
    static int ReadListFile(std::fstream file);
    static int WipeFile(char* fname);
    static int WriteBuffer(std::fstream file, char* Buffer);
};

...

int FileData::OpenListFile(std::fstream file, char* fname) {
    file.open(fname, std::fstream::in);
    return file.bad() ? -1 : 0;
}

...

std::fstream ListFile;
if ((ccode = FileData::OpenListFile(ListFile, fspec3)) != 0) {
   // ....
}

也就是说,请注意您不能传递std::fstream 按值,因为std::fstream 不可复制。您需要通过引用通过指针传递它:

...
int OpenListFile(std::fstream& file, char* fname);
...
...
int OpenListFile(std::fstream* file, char* fname);
...

【讨论】:

  • 值得注意的是,拥有一个你从不实例化的“类”,它只是塞满了static 方法,实际上根本就不是一个类。
  • @tadman 当然,它们可以改为namespace 中的一堆独立函数。
  • @RemyLebeau 感谢您的准确回复。今天早些时候,我找到了关于通过引用或指针传递 fstream 的答案。几年前我已经开始学习 C 了,在远离编程多年之后,我肯定正在追赶学习 C++,这在事情的工作方式上是一个巨大的差异。谢谢。
猜你喜欢
  • 1970-01-01
  • 2019-06-20
  • 2020-02-02
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
相关资源
最近更新 更多