【问题标题】:How to fix "invalid use of incomplete type" in c++如何在 C++ 中修复“不完整类型的无效使用”
【发布时间】:2019-09-06 21:09:16
【问题描述】:

我想通过使用一个班级的方法在两个班级之间建立友谊。即使我查看了不同的教程和书籍,我也无法让它发挥作用。

编辑:: 它在一个文件中工作,但我想在单独的文件中制作它 - 不幸的是不能这样做:

Tbase_in_memory.h:

#ifndef FRENDY_TBASE_IN_MEMORY_H
#define FRENDY_TBASE_IN_MEMORY_H

#include <iostream>
#include <string>
#include <fstream>

class base;

class Tbase_in_memory
{
public:
    Tbase_in_memory(int = 2);
    ~Tbase_in_memory();
    void read_to_arrays(base & b);

private:
    std::string *name;
    double      *price_tag;
    int         *code;
    char        *type;
    int         _size;
};

#endif

Tbase_in_memory.cpp:

#include "Tbase_in_memory.h"

using namespace std;

class base;
Tbase_in_memory::Tbase_in_memory(int s)
{
    _size = s;
    name = new string[_size];
    price_tag = new double[_size];
    code = new int[_size];
    type = new char[_size];
}

Tbase_in_memory::~Tbase_in_memory()
{
    delete[] name;
    delete[] price_tag;
    delete[] code;
    delete[] type;
}

void Tbase_in_memory::read_to_arrays(base & b)
{
    string line;
    while (getline(b.file, line)) {
        cout << line;
    }
}

base.h:

#ifndef FRENDY_BASE_H
#define FRENDY_BASE_H

#include <iostream>
#include <string>
#include <fstream>
#include "Tbase_in_memory.h"

class base
{
public:
    base(std::string = "...");
    ~base();
    friend void Tbase_in_memory::read_to_arrays(base & b);
private:
    std::fstream    file;
    std::string     f_name;
};

#endif

base.cpp

#include "base.h"

using namespace std;

base::base(string n)
{
    f_name = n;
    file.open(f_name, ios::in);

    if (!file.good()) {
        cout << "Error";
        cout << string(38, '-');
        exit(0);
    }
}

base::~base()
{
    file.close();
}
#include <iostream>
#include "Tbase_in_memory.h"
#include "base.h"

using namespace std;

int main()
{
    base b("/home/Sempron/Desktop/code");
    Tbase_in_memory a;
    a.read_to_arrays(b);
    return 0;
}

我遇到了错误:

"error: invalid use of incomplete type ‘class base’
     while (getline(b.file, line)) {". 

"forward declaration of ‘class base’
     class base;"

【问题讨论】:

  • 当编译器试图解析friend void Tbase_in_memory::read_to_arrays(base &amp; b);时,没有Tbase_in_memory::read_to_arrays。挖一个骗子。
  • Tbase_in_memory的完整声明移到base上方。在Tbase_in_memory上方转发声明class base;
  • 无关:与其在Tbase_in_memory 中分配和维护一小群动态数组,不如考虑将数据聚合到一个结构中并创建一个数组(std::vector,如果你有' em) 的那个结构。 vector 的额外好处是您不必注意Rule of Three,因为vector 遵守五法则。现在,如果您不小心复制了 Tbase_in_memory,那么您将陷入痛苦的世界。
  • 顺便说一句,不需要欺骗。 @jxh 的解决方案比我发现的任何骗子都优雅。

标签: c++ oop friend friend-function


【解决方案1】:

在声明friend 引用时,被授予友谊访问权限的函数的原型/定义必须存在。固定代码(包含):

#include <string>
#include <iostream>
#include <fstream>

using namespace std;

class base;

class Tbase_in_memory
{
public:
    Tbase_in_memory(int = 2);
    ~Tbase_in_memory();
    void read_to_arrays(base & b);

private:
    std::string *name;
    double      *price_tag;
    int         *code;
    char        *type;
    int         _size;
};

class base
{
public:
    base(std::string = "...");
    ~base();
    friend void Tbase_in_memory::read_to_arrays(base & b);
private:
    std::fstream    file;
    std::string     f_name;
};

Tbase_in_memory::Tbase_in_memory(int s)
{
    _size = s;
    name = new string[_size];
    price_tag = new double[_size];
    code = new int[_size];
    type = new char[_size];
}

Tbase_in_memory::~Tbase_in_memory()
{
    delete[] name;
    delete[] price_tag;
    delete[] code;
    delete[] type;
}

void Tbase_in_memory::read_to_arrays(base & b)
{
    string line;
    while (getline(b.file, line)) {
        cout << line;
    }
}

base::base(string n)
{
    f_name = n;
    file.open(f_name, ios::in);

    if (!file.good()) {
        cout << "Error";
        cout << string(38, '-');
        exit(0);
    }
}

base::~base()
{
    file.close();
}

int main()
{
    base b("/home/Sempron/Desktop/code");
    Tbase_in_memory a;
    a.read_to_arrays(b);
    return 0;
}

理想情况下,这两个类将在不同的头文件中声明,因此您必须仔细观察包含顺序。

【讨论】:

  • 嗨!谢谢你和@jxh 的回答。它在一个 .cpp 文件中工作,但是当我将类分成不同的 .cpp 和 .h 文件时 - 它不起作用,我真的不知道为什么。你能解释一下如何使它与标题一起使用吗?对此我将不胜感激。
  • @Sempron 添加#include "base.h"Tbase_in_memory.cpp 在所有其他包括之后。那是cpp 文件,而不是h 文件。可以选择删除同一文件中的类原型 class base; edit: @jxh 击败了我。
【解决方案2】:

在文件Tbase_in_memory.cpp 中,您还需要包含base.h。然后就可以去掉cpp文件中的前向声明了。

#include "Tbase_in_memory.h"
#include "base.h"

using namespace std;

Tbase_in_memory::Tbase_in_memory(int s)
{
    //...

【讨论】:

    猜你喜欢
    • 2016-02-12
    • 2017-10-24
    • 2010-10-13
    • 2018-12-17
    • 2021-08-12
    • 2015-11-24
    • 1970-01-01
    • 2013-05-19
    相关资源
    最近更新 更多