Home > Mobile >  Importing and inheriting class from h-file. "Base class undefined"
Importing and inheriting class from h-file. "Base class undefined"

Time:01-05

I am working on a small project with three classes. But my code won't compile. These classes are PacketObject2, PacketList2 and PacketInt2.

The code won't compile with the error 'PacketObject2': base class undefined in both PacketInt2.h and PacketList2.h.

PacketObject2.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 does not have a cpp-file.

PacketList2.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;
    }
}

I think I have done something with the imports that doesn't work. I am very new to the concept of h-files. Can you guys help me understand what is wrong?

CodePudding user response:

Rewrite like this

#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();

};

The forward declaration of PacketList2 allows you to remove the inclusion of "PacketList2.h" which breaks the cycle of header file includes.

I've also removed using namespace std; which is bad practice at the best of times but a sackable offense when placed in a header file.

Also, not what you asked about, but this is wrong

int PacketInt2::CompareTo(PacketObject2 other) {
    PacketInt2* otherPtr = dynamic_cast<PacketInt2*>(&other);

Should perhaps be this

int PacketInt2::CompareTo(PacketObject* other) {
    PacketInt2* otherPtr = dynamic_cast<PacketInt2*>(other);

or maybe this

int PacketInt2::CompareTo(const PacketObject& other) const {
    const PacketInt2* otherPtr = dynamic_cast<const PacketInt2*>(&other);

In your version other has lost it's polymorphic nature so the dynamic_cast is guaranteed to fail. In C polymorphism only works on pointers and references (like both of my suggestions). This issue is known as object slicing which you might want to research.

I'm getting former Java programmer vibes.

  •  Tags:  
  • c
  • Related