Hi,

I have a class named 'roomOne' and another named 'StoneAdventure'. 'roomOne' inherits from 'StoneAdventure'.
Heres the Problem: Whenever I create an #include "roomOne.h" in the header file of 'StoneAdventure' I get an error C2504: base class is undefined.
Note: Everything works fine if I remove the #include "roomOne.h" from the StoneAdventure.h. I need to create the roomOne Object in the StoneAdventure.h so it can be accessed by the functions.

Am I going on this the wrong way??

#ifndef StoneAdventure_H
#define StoneAdventure_H
#include "Controls.h"
#include "RoomOne.h"
#include <iostream>
using  namespace std;

namespace ROOMS{
    enum emun
    {
        ROOM1,
        ROOM2,
    };
}

using namespace ROOMS;

class StoneAdventure: public Controls
{
public:
    StoneAdventure();
    ~StoneAdventure();
    void render();
private:

};

#endif



#ifndef RoomOne_H
#define RoomOne_H
#include "StoneAdventure.h"
#endif // !RoomOne_H

class RoomOne: public StoneAdventure
{
public:
    RoomOne();
    ~RoomOne();
    void render();
private:
    void ifGo();
    void ifLook();
    void ifInventory();
    void ifOpen();
    void ifClose();
    void ifAttack();
    void ifTake();
    void ifPut();
    void ifDrop();
};

Am I going on this the wrong way??

Yes.

To begin with, it doesn't make any sense to me that a RoomOne is a kind of StoneAdventure (and that's what inheritance does; if X inherits from Y, then X is a specialised kind of Y, and can be used anywhere that a Y can be used). It also makes no semantic sense to me that a StoneAdventure is a kind of Controls. If you create inheritance chains that don't make sense when you think about them, you are making it hard for yourself.

I need to create the roomOne Object in the StoneAdventure.h

Sounds to me like what you need is for the StoneAdventure object to contain a roomOne object. I seem to recall this is what some textbooks call composition.

Does your roomOne object really need to be a complete StoneAdventure object? Because that's what inheritance does.

I suggest that roomOne shoudl NOT be a StoneAdventure object, but that your StoneAdventure object should contain a roomOne object, like this:

class StoneAdventure: public Controls
{
public:
StoneAdventure();
~StoneAdventure();
void render();
private:
RoomOne theFirstRoomObject;

};

Without knowing quite what you're trying to do, I can only guess, but the simple semantic nonsense that a roomOne object (which intuitively should be one of many rooms that are all part of a StoneAdventure) is itself a complete StoneAdventure object, seems nonsensical.

One of the largest benefits of OOP and inheritance (in my opinion; religious wars loom!) is that you can do yourself a favour and make it easy to think about somes problem in a way that makes it easier to code (and when OOP and objects and all the rest of it don't make thinking about a specific problem any easier, maybe OOP and objects and all the rest is not the way to go for that particular problem). Thinking about the problem is, in my experience, the part of coding that people find hardest, and not thinking clearly about the problem leads to some truly horrific code.

I would think about this and decide that a StoneAdventure should contain many rooms. I would not think that a room should itself be a whole, complete StoneAdventure object.

Edited 2 Years Ago by Moschops

Sounds to me like what you need is for the >StoneAdventure object to contain a roomOne >object. I seem to recall this is what some >textbooks call composition.

I looked it up, yes I am.

Does your roomOne object really need to be >a complete StoneAdventure object? Because >that's what inheritance does.

If theres another way other than an inheritance, but so far thats the only way o know how. I want to access some functions and data in StoneAdventure class without creating a new StoneAdventure class object in RoomOne object. I will have multiple rooms and I want those rooms to change and check some values that are in StoneAdventure Object that called them (the rooms). Basically, I only want 1 StoneAdventure Object created and in that object are multiple room objects. those room objects will take and change values that are in that StoneAdventure Object.

Put #endif // !RoomOne_H at the end of >RoomOne.h and don't include RoomOne.h in >StoneAdventure.h

I tried this and I still got the same error.

Edited 2 Years Ago by HuePig

Well you can have the StoneAdventure class hold a vector of rooms and then you can declare room to be a friend of StoneAdventure.

What follows below is more general discussion than hard fact. It's opinion. Nonetheless, I think that it's worth thinking about.

Basically, I only want 1 StoneAdventure Object created and in that object are multiple room objects.

Well then, here is your StoneAdventure class, with multiple room objects inside it. I've called them RoomObject - it seems to me that EVERY room you make should be some kind of basic RoomObject class, and then you give them different internal values to differentiate room one from room two and so on; creating a whole class for room one, and a whole class for rom two, and a whole class for room three, etc etc., is just missing the point of classes. The point of classes is that you design it once (e.g. a RoomObject class) and then you make as many of them as you like (room 1, room 2, room 3, etc etc.)

class StoneAdventure: public Controls
{
public:
StoneAdventure();
~StoneAdventure();
void render();
private:
RoomObject theFirstRoomObject;
RoomObject theSecondRoomObject;
RoomObject theThirdRoomObject;
};

As you can see, each of the rooms are the same kind of object - a RoomObject. There's nothing special about this. Each RoomObject is a separate, distinct instance of the RoomObject class, and each can have different internal values and all that sort of thing. Your StoneAdventure class has access to every one of them.

If you want the room objects to be able to affect values in the StoneAdventure class, like an int, for example:

    class StoneAdventure: public Controls
    {
    public:
    StoneAdventure();
    ~StoneAdventure();
    void render();
    private:

    RoomObject theFirstRoomObject;
    RoomObject theSecondRoomObject;
    RoomObject theThirdRoomObject;

    int someValue;
    };

you could do this in many ways. You could have a function in the RoomObject that returns an int value that you use to alter someValue, or the RoomObjects could contain pointers to these StoneAdventure values that they need to change, or various other ways; maybe the someValue could be controlled by StoneObject functions:

    class StoneAdventure: public Controls
    {
    public:
    StoneAdventure();
    ~StoneAdventure();

    void setIntValue(int newValue);
    int getIntValue();

    void render();
    private:

    RoomObject theFirstRoomObject;
    RoomObject theSecondRoomObject;
    RoomObject theThirdRoomObject;

    int someValue;
    };

Above, I have added setIntValue and getIntValue.

Your options are wide and varied. You will definitely do yourself a favour by modelling the problem sensibly. If the model inside your head of StoneAdventure is meant to contain all the rooms, then have it contain all the rooms in the code.

perhaps you'd like to not have to specify how many rooms there will be, but add them as needed.

    class StoneAdventure: public Controls
    {
    public:
    StoneAdventure();
    ~StoneAdventure();

    void setIntValue(int newValue);
    int getIntValue();

    addRoom(RoomObject);

    void render();
    private:

    vector<RoomObject> allTheRooms;


    int someValue;
    };

Now, I've created a vector of RoomObject that you can add rooms to as you need them, through the function addRoom. This way, you can change the number of rooms as you go, adding or removing. The possibilties expand...

Definitely, though, do not have your room objects inherit from your StoneAdventure object. While you're learning, I very much recommend that if you cannot say sensibly to yourslef "THIS is a kind of THAT", then do not have THIS inherit from THAT. Sure, it's legal code to do so, but legal code is a tiny part of programming; you need to be able to think about the code and think about the problem.

Is a ROOM a kind of STONEADVENTURE? No!
Is a STONEADVENTURE a kind of CONTROL? I expect not :)

Edited 2 Years Ago by Moschops

Correct me if im wrong.. I've always thought that when the word 'kind' is thrown in a sentence that means we're working with polymorphism. Also, the relationship between the base class and derived class is like a parent and a child.. that's an analogy my teacher said to me. Example, if I have a parent class and one function of that class is surname() the drived class, in this case the daughter, can inherit that surname() and all public and protected functions.

Back on the topic, I decided to pass by reference StoneAdventure when I create the room1 obj.

 class StoneAdventure: public Controls
    {
    public:
    StoneAdventure();
    ~StoneAdventure();
    void render();
    private:
    RoomOne rOne(StoneAdventure sAdv);
    };

    StoneAdventure(): RoomOne(this){}
    ...

What do you guys think?

Also, the relationship between the base class and derived class is like a parent and a child.. that's an analogy my teacher said to me.

As with many analogies in computing, that's pretty bad. An anaology is meant to help you think about the situation. When I think of child inheriting something from a parent, it means that the parent has to be dead, and exactly what the child inherits can be different every time depending on the will. That's got very little in common with inheritance in programming.

Dump bad analogies. They don't help. It's far easier to just remember that when you inherit one class from another, you can reuse the base class' functions if you want, or you can rewrite them in the new class, and you can add things as well, and if you're careful you can now use the new class where previously you were using the base class (which is a nice sanity check; if it makes no sense to replace your StoneAdventure object with a Room object, you've done yourself no favours in your design). The actual mechanics of public, private, protected etc can be easily checked when you need them.

The biggest problems your code was having wasn't in the mechanics in of inheritance; it was in thinking sensibly about the problem with the tools and concepts available, and that's the hardest part of programming. The rest is just memorising syntax.

Edited 2 Years Ago by Moschops

if it makes no sense to replace your >StoneAdventure object with a Room object, >you've done yourself no favours in your design

yeah, I dont want to replace StoneAdventure. I want them to exist at the same time. I'll re-think my design. tnx.

This question has already been answered. Start a new discussion instead.