【问题标题】:Importing and inheriting class from h-file. "Base class undefined"从 h 文件导入和继承类。 \"基类未定义\"
【发布时间】:2023-01-04 23:46:36
【问题描述】:

我正在做一个有三个班级的小项目。但是我的代码不会编译。这些类是数据包对象2,PacketList2PacketInt2.

代码将不会在PacketInt2.hPacketList2.h 中编译并出现错误'PacketObject2': base class undefined

数据包对象2.h:

#pragma once
#include <iostream>

#include "PacketList2.h";

using namespace std;

class PacketObject2
{
public:
    virtual void Print();

    virtual int CompareTo(PacketObject2 other);

    virtual PacketList2 ToList();

    virtual bool IsOpen();

    virtual void AddInt(int value);

    virtual void OpenChild();

    virtual void CloseChild();

};

PacketObject 没有 cpp 文件。

数据包列表2.h:

#pragma once
#include "PacketObject2.h"
#include "PacketInt2.h"

#include <vector>
#include <iostream>

using namespace std;

class PacketList2 : public PacketObject2
{
private:
    vector<PacketObject2> objectsInList;
    bool isOpen;
public:

    PacketList2();
    PacketList2(PacketInt2 pi);

    PacketList2 ToList();

    void Print();

    int CompareTo(PacketObject2 other);

    void AddInt(int value);

    bool IsOpen();

    bool HasOpenChild();

    void OpenChild();

    void CloseChild();
};

PacketList2.cpp:

#include "PacketList2.h"
#include "PacketObject2.h"
#include "PacketInt2.h"


vector<PacketObject2> objectsInList;
bool isOpen = true;

PacketList2::PacketList2() {

}
PacketList2::PacketList2(PacketInt2 pi) {
    objectsInList.push_back(pi);
}

PacketList2 PacketList2::ToList() {
        return *this;
    }

void PacketList2::Print() {
    cout << '[';
    for (int i = 0; i < objectsInList.size(); i++) {
        objectsInList[i].Print();
        cout << ',';
    }
}

int PacketList2::CompareTo(PacketObject2 other) {
    PacketList2 otherList = other.ToList();
    for (int i = 0;
        i < min(objectsInList.size(), otherList.objectsInList.size());
        i++) {
        int comparison = objectsInList[i].CompareTo(otherList.objectsInList[i]);
        if (comparison != 0) {
            return comparison;
        }
    }
    return 0;
}

void PacketList2::AddInt(int value) {
    if (objectsInList.back().IsOpen()) {
        objectsInList.back().AddInt(value);
    }
    else {
        PacketInt2 pi(value);
        objectsInList.push_back(pi);
    }
}

bool PacketList2::IsOpen() {
    return isOpen;
}

bool PacketList2::HasOpenChild() {
    return objectsInList.back().IsOpen();
}

void PacketList2::OpenChild() {
    if (HasOpenChild()) {
        objectsInList.back().OpenChild();
    }
    else {
        PacketList2 pl;
        objectsInList.push_back(pl);
    }
}

void PacketList2::CloseChild() {
    if (HasOpenChild()) {
        objectsInList.back().CloseChild();
    }
    else {
        isOpen = false;
    }
}

PacketInt2.h:

#pragma once
#include "PacketList2.h"
#include "PacketObject2.h"

using namespace std;

class PacketInt2 : public PacketObject2
{
private:
    int value;
public:
    PacketInt2(int value);

    void Print();

    PacketList2 ToList();

    int CompareTo(PacketObject2 other);
};

PacketInt2.cpp:

#include "PacketInt2.h"
#include "PacketList2.h"

int value;

PacketInt2::PacketInt2(int value) {
    this->value = value;
}

void PacketInt2::Print() {
    cout << value;
}

PacketList2 PacketInt2::ToList() {
    PacketList2 pl(*this);
    return pl;
}

int PacketInt2::CompareTo(PacketObject2 other) {
    PacketInt2* otherPtr = dynamic_cast<PacketInt2*>(&other);
    if (otherPtr == nullptr) {
        return ToList().CompareTo(other);
    }
    if (otherPtr->value == value) {
        return 0;
    }
    if (value < otherPtr->value) {
        return 1;
    }
    if (value > otherPtr->value) {
        return -1;
    }
}

我想我对不起作用的进口做了一些事情。我对 h 文件的概念很陌生。你们能帮我理解什么是错的吗?

【问题讨论】:

  • 你交叉包括两个标题。选择订单。
  • 该错误提到了基类,它发生在方法声明之前。这应该是一个线索,表明您可以大大简化您的 minimal reproducible example 对于这个问题。它表明在指定基类之后的细节可能是可删除的。尝试删除类方法,将 PacketList2 的定义简化为 class PacketList2 : public PacketObject2 {};。然后编译以确保问题仍然重现。然后重复PacketInt2
  • PacketList2.h包括PacketObject2.h,后者又包括PacketList2.h。仔细考虑当编译器读取这些头文件时会发生什么(特别是考虑到#pragma once)。那么错误应该是有道理的,解决方案是不要让两个头文件相互包含。使用前向声明和/或类外方法定义来打破循环。
  • 参见Resolve build errors due to circular dependency amongst classes(可能不是重复的,因为它没有使用基类,但原理是相似的)。

标签: c++


【解决方案1】:

像这样重写

#pragma once
#include <iostream>

class PacketList2; // forward declaration

class PacketObject2
{
public:
    virtual void Print();
    virtual int CompareTo(PacketObject2 other);
    virtual PacketList2 ToList();
    virtual bool IsOpen();
    virtual void AddInt(int value);
    virtual void OpenChild();
    virtual void CloseChild();

};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-12
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多