Putting the 'role' back in role-playing games since 2002.
Donate to Codex
Good Old Games
  • Welcome to rpgcodex.net, a site dedicated to discussing computer based role-playing games in a free and open fashion. We're less strict than other forums, but please refer to the rules.

    "This message is awaiting moderator approval": All new users must pass through our moderation queue before they will be able to post normally. Until your account has "passed" your posts will only be visible to yourself (and moderators) until they are approved. Give us a week to get around to approving / deleting / ignoring your mundane opinion on crap before hassling us about it. Once you have passed the moderation period (think of it as a test), you will be able to post normally, just like all the other retards.

I'm getting "Base class undefined" even though I did define the bloody thing.

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
C++

I have three files, Base_Equip, Base_Weapon and Base_Armor. I'm trying to make Base_Weapon and Base_Armor inherit from Base_Equip, but I always get the fucking "Base class undefined" message. I managed to get one working, but not the other. Now, none are working. At some point, just putting an include to Base_Equip on them broke the program, without even trying to make them inherit shit. I looked at the order of the includes elsewhere and tried to put "#include "Base_Equip.h"" first on the order in the other files. But it didn't work.

I'm at a loss here.

Here's Base_Equip, Base_Armor and Base_Weapon. The way they're listed here, with the inheritance and "#include "Base_Equip" commented, the program runs. If I just uncomment the "#include "Base_Equip" thing, something else breaks, like Dummy_Weapon, which inherits from Base_Weapon, starts complaining about "Base class undefined". Besides those files, the project has around 20 other files, so I can't paste all here. If any of you want it, ask me, and I'll upload it somewhere.

#pragma once
#include <vector>
#include "Skill.h"

class Base_Equip
{
public:
Base_Equip();
virtual ~Base_Equip()
{
}

protected:
//std::vector<Skill*> Equip_Skills;
//enum_Equip_Type Type;
//std::string string_name;
};

#pragma once
#include "SDL.h"
#include "struct.h"
#include "Base_Equip.h"

class Base_Armor //: public Base_Equip
{
public:
Base_Armor()
{
}
virtual ~Base_Armor()
{
}

struct_armor Return_Stats()
{
return armor_stats;
}

protected:
struct_armor armor_stats;

std::vector<Skill*> Equip_Skills;
enum_Equip_Type Type;
std::string string_name;
};

#pragma once
#include "struct.h"
#include <vector>
//#include "Base_Equip.h"

class Base_Weapon //: public Base_Equip
{
public:
Base_Weapon();
virtual ~Base_Weapon()
{
}
virtual struct_buff Attack();
int Return_Range();

protected:
int int_damage_type;
int int_accuracy;
int int_min_damage;
int int_max_damage;
int int_crit_chance;
int int_kill_chance;
int int_range;
int int_attack_speed;
int int_pen_chance;

int int_number_of_hands;
};
 

hrose

Educated
Joined
Jan 6, 2003
Messages
90
I'm like 2 weeks into learning c++, but...

why do you need to repeat stuff like "std::vector<Skill*> Equip_Skills;" under Base_Armor if it's stuff already inherited from Base_Equip?

Wouldn't make more sense to uncomment that part in Base_Equip (since it's the base class), and comment it in Base_Armor (since it's derived from Base_Armor, and so inherits its properties)?
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
I'm like 2 weeks into learning c++, but...

why do you need to repeat stuff like "std::vector<Skill*> Equip_Skills;" under Base_Armor if it's stuff already inherited from Base_Equip?

Wouldn't make more sense to uncomment that part in Base_Equip (since it's the base class), and comment it in Base_Armor (since it's derived from Base_Armor, and so inherits its properties)?

You're right, but since I was testing, sometimes I needed those declarations in Base_Armor and sometimes in Base_Equip. I would leave one commented while the other was uncommented, and vice versa for testing purposes.
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
tldr but

thats not proper hungarian

int int_damage_type;
int int_accuracy;
int int_min_damage;
int int_max_damage;
int int_crit_chance;
int int_kill_chance;
int int_range;
int int_attack_speed;
int int_pen_chance;

int int_number_of_hands; // lotsa hands eh

http://www.joelonsoftware.com/articles/Wrong.html

iStupidNamingConvention is harder for me to read than int_Stupid_Naming_Convention.

sBullshit is probably going to get me wondering what the fuck that "s" is when I'm sleepy, while string_Bullshit won't.

Fuck proper hungarian, it's my fucking code, I write it any I way I damn please.
 

hrose

Educated
Joined
Jan 6, 2003
Messages
90
You're right, but since I was testing, sometimes I needed those declarations in Base_Armor and sometimes in Base_Equip. I would leave one commented while the other was uncommented, and vice versa for testing purposes.

Then you don't have vector included in Base_Armor
 
Self-Ejected

Davaris

Self-Ejected
Developer
Joined
Mar 7, 2005
Messages
6,547
Location
Idiocracy
The fastest way to track down bugs, is to copy the error message and search on it Google. Chances are the question has already been asked and answered somewhere.

I'd be adding the following to each header:


#ifndef Base_Equip_h
#define Base_Equip_h

namespace Game
{

class Base_Equip
{
....
};

}

#endif


In the cpp file after the include files and before your code add the following:

using namespace Game;

I assume your constructors for Base_Equip and Base_Weapon are defined in your cpp files?
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
You're right, but since I was testing, sometimes I needed those declarations in Base_Armor and sometimes in Base_Equip. I would leave one commented while the other was uncommented, and vice versa for testing purposes.

Then you don't have vector included in Base_Armor

It's compiling without it (as long as I don't mess with Base_Equip). It's probably included in a file that's loaded before Base_Armor (that's my best guess, anyway).
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
The fastest way to track down bugs, is to copy the error message and search on it Google. Chances are the question has already been asked and answered somewhere.

I'd be adding the following to each header:


#ifndef Base_Equip_h
#define Base_Equip_h

namespace Game
{

class Base_Equip
{
....
};

}

#endif


In the cpp file after the include files and before your code add the following:

using namespace Game;

I assume your constructors for Base_Equip and Base_Weapon are defined in your cpp files?

Of course I already tried google, believe me, posting here is usually my last option, but usually this problem amounts to somebody forgetting the header guard and/or forgetting to include the base class file. #pragma once is my header guard, and I didn't forget to include the file. In fact, including the file IS what is fucking my code.

I have suspected that it might be some circular dependency, but this part is more or less detached from the main code, and I can't see any.

Correct me if I'm wrong, but doesn't #pragma once work the same as those indefs?

The constructors are indeed defined in the .cpp, and they're blank, like Base_Armor.

I have yet to read on namespaces, tho.
 

odrzut

Arcane
Joined
Apr 30, 2011
Messages
1,082
Location
Poland
Even without namespaces all should work, because everything is by default in the same namespace. Namespace would be the problem only, if you added one class to different namespace than the other, and didn't appended the namespace before the reference to this class in different classes.
But from the code included it doesn't look like you did.

I never used #pragma once, I always do #ifndef STH_H , maybe it has some wierd side effects? Or maybe your compilator don't understand #pragma once and it includes the code a few times and that mess something? Pragmas are compiler-specific, ifndefs are portable way to do it.

But this would most probably produce error that symbol xxx already defined or sth like that..

Do you have dependencies between classes (and includes between files) declared the right way? Are there cycles in your dependencies? Can you write the graph of dependencies between your header files there?
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
Using my powers of manliness I solved it.

It wasn't a call for weapon and armor headers in skill.h, but it was indeed Skill.h related.

You see, Entity.h has a circular thinguie with Skill.h. One needs the other, and there's no way around it, so Alex told me to write "class Skill;" in Entity and then include Entity inside Skill.h. He failed to tell me that I need to call Entity first in my program tho. Or did he? I don't remember very well.

Anyway, since there's a call for Skill.h in the Base_Equip (and Base_Armor, which was fucking things up even when Base_Equip was disabled, because I was transfering code that needed Skill.h to work), Skill.h was being called before Entity.h, and the circular dependency thing was occurring again and fucking shit up.

I commented the #include "Skill.h" and commented the lines that needed that include. The inheritances worked fine. Then I changed #include "Skill.h" for #include "Entity.h" and uncommented the lines that need Skill.h. Voila, it still works!

Thanks for the input, guys.

@Devaris, I would totally find that on google.
 
Joined
May 10, 2011
Messages
1,059
Well, I wouldn't call that 'solved'. Having to include entity.h when you actually want to include skill.h will give you more wtf moments than hungarian notation. You probably should not include skill.h inside entity.h or something along those lines.
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
Well the problem with the Base_Equip/Base_Weapon/Base_Armor is solved.

Entites (either PC classes or monsters) have skills. No way around that. And I need a pointer inside a skill to point to its owner. I don't remember why I needed a pointer to the owner, but I remember it's like, super important or some shit.

Oh, right, I need it because a skill modifies the owner. For the most obvious example, it subtracts mana, but there's several other things as well.
 
Joined
May 10, 2011
Messages
1,059
You don't need to include anything if you're just declaring a pointer. Using 'class ClassName;' will suffice.
 
Self-Ejected

Davaris

Self-Ejected
Developer
Joined
Mar 7, 2005
Messages
6,547
Location
Idiocracy
Correct me if I'm wrong, but doesn't #pragma once work the same as those indefs?

It isn't part of the iso standard, so I wouldn't use it.

Google this and decide from the discussions for yourself.

#pragma once iso standard
 

J1M

Arcane
Joined
May 14, 2008
Messages
14,616
This thread was very helpful to me. It reminded me why I only use C# for personal projects. :lol:
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
The only reason C++ has headers, ifdefs, macro-generator and other archaic shit like that is because they really really wanted it to be a superset of C (and failed :lol:)

Actually the archaic include and macro model is the main reason C++ compilation is so slow (the other reason being extreme optimization passes/template specialization).
 

J1M

Arcane
Joined
May 14, 2008
Messages
14,616
This thread was very helpful to me. It reminded me why I only use C# for personal projects. :lol:

You don't need to deal with that crap using C#?
Nope. C# is like Java but designed by smart people. :P

In C# you don't have to worry about header files, forward declarations, or remembering to free up memory. Less time spent on housekeeping tasks and more on game logic. Many of the things that C++ is sorely lacking and leans on frameworks like Boost or Qt to offer is built into the language. Strings, foreach, etc.
 

No soup for you!

Guest
In C# you don't have to worry about header files, forward declarations, or remembering to free up memory. Less time spent on housekeeping tasks and more on game logic. Many of the things that C++ is sorely lacking and leans on frameworks like Boost or Qt to offer is built into the language. Strings, foreach, etc.

C#'s memory management model can be a little more complex than it seems at first due to the differing behavior of destructor and IDisposable semantics. It's not *overwhelmingly* complex, but you still have to keep such things in mind when dealing with resource-touching code. In a high performance application you will also need to pool objects and defer deletion to prevent the GC from stalling the game at an inopportune moment.

In practice memory and resource management in C# requires similar discipline as C++ when writing high performance applications. Of course, you do get the syntactical sugar and other bonuses you listed. Just something to keep in mind.
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
Not quite the same level of discipline. A subset. Though C++ has a neat feature in RAII (only for stack objs) that isn't implemented in VM's because they only use stack allocation dynamically when the goddamned JIT gets off it's ass (so they can't depend on the stack unwinding).
Finalizers in VM languages are worse than useless for 'destruction' too (unfortunately needed for spec guarantees) - they mislead newbs to think it's the same as a destructor.

Pooling objects sucks, you're right about that (there are many dirty techniques that are alternatives, including the flyweight pattern, delete-elements-by-moving-references-to-another-list-and-clearing-the-old-and-switching-references and other non-general crap like that). Though since VM's started to stack allocate in methods it's gotten much better - still need to profile that shit though, it might not be the GC even, but the constructor or something.

What i find hilarious about current compiler thinking is that everyone recognizes that C pointer arithmetic was a mistake... for... tundumdumdum... performance reasons

The next generation languages will have no pointer arithmetic be they compiled or not.
 

As an Amazon Associate, rpgcodex.net earns from qualifying purchases.
Back
Top Bottom