c++ basics?

Started by
12 comments, last by persil 18 years, 8 months ago
Ok so I have a blank class p class p{}; then a couple of classes such as class x : public p { void func1() }; class y : public p { void func2() }; So in code I define a pointer type p p *myP; ...In the hope that at run time I can create an X or Y such as if(casey==1) myP = new x; else mpP = new y; ok, so then how do I access members of x or y without using virtual functions in p? Because the following sure dont work. myP->func2(); How might I do this? The problem is that I'm using a blank base class, as my derived classes have nothing in common that I could make virtual. Thanks DaveC
Advertisement
Quote:Original post by bobason456
<snip>
...as my derived classes have nothing in common that I could make virtual.


Your code is trying to tell you something. If they have no common interface, they don't belong in the same inheritance tree.



yes :), that's a very good point.

But I was trying to create a list of unrelated classes. I know this is probably not a good idea. What would you suggest?
if you could describe the application a bit more, im sure one of the bright cookies around here will be able to give you an ideal answer [wink]

Cheers
-Danu
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
If you have a base class, then you should probably define a virtual destructor, otherwise delete will do wild weird things that probably aren't healthy for your application. Once you have a virtual destructor you can use dynamic_cast<> to get a pointer to the actual class.

However, from your code so far, there doesn't seem to be any reason to lose the type information from the original pointer in the first place. (And there doesn't seem to be a reason for them to be descended from the same base.)
Really, your best solution is not creating a list of unrelated classes [smile].

Basically, if they have nothing in common, then they shouldn't be in the same inheritance hirachy, and thusly you shouldn't be creating lists of totally unrelated classes. The best solution probably is to use several lists.


Alternitivly, if all they have in common is that they must go into the list together (which is highly unusual and you should rethink your design), inheriting (or multiple-inheriting) from the "p" class you have there is probably the best solution.

Then what you probably want to look at is the dynamic_cast operator. [edit: SiCrane beat me to it - and as he says - virtual destructor may be necessary]
Quote:Original post by bobason456
yes :), that's a very good point.

But I was trying to create a list of unrelated classes. I know this is probably not a good idea. What would you suggest?


The objects you want to place in the list aren't probably as unrelated as you think. Why would you want to put completely unrelated objects in the same list?
I'm guessing you've done some programming in Java before. You need to get in the C++ state of mind. ;)
Create a wrapper system using some template magic and/or RTTI, or, what's better, grab a ready-made library created just for such purposes. Recommended reading: boost::variant and boost::any.
Ok, thanks for that.. here is a little more information.

I’m creating an asset management system, something I though would be simple at first. So I have a base class asset that is blank then I have other classes such as Texture, Mesh, Object and so on that inherit this.

Class Casset {// nothing here};
Class Ctexture : public asset { // texture stuff };
Class Cmesh : public asset { // mesh stuff };
Class Cobject : public asset { // object stuff };

I have an asset management class that checks if the asset is loaded, maintains the list of assets, returns pointers to the assets and so on. Also a Node class that forms the linked list used by the asset management class.

Class CNode
{
Casset *TheAsset;
CNode *NextNode;
int AssetID;
// all the usual linked list stuff
};

Class CAsset_Manager
{
CNode *FirstNode
Casset findAsset(int assetID);
// all the usual linked list stuff
};

The findAsset function searched all the Nodes for the assetID, if it does not exist then it gets created and added to the list.

I’ve left out a lot of code here, but I had the Asset_Manager working and all the classes were being created correctly, and destroyed. I just had not though far enough ahead to where I actually needed to access the Assets member functions.

Because the Mesh class has completely different structure to that of a Texture class.

My hope was (again without thinking about it) that I could do this.

New Casset tasset = AssetManager.findAsset(1);
tasset->”some texture member function if this is a texture”;
// does not work because Casset has no member function.

or

New Ctexture tTexture = AssetManager.findAsset(1);
tTexture->”some texture member function if this is a texture”;
// does not work because findAsset returns a Casset

hmm?
Ok, first things first, what you are attempting to do is very legitimate. Take a look at this and tell me if it is that unrelated:

class asset{public:  asset( const string & res )    : last_accessed_( 0 ), loaded_( false ), resource_link_( res )  {  }  virtual ~asset() = 0;  bool loaded() const;  time_t last_accessed() const;protected:  virtual bool load() = 0; // These are defined in derived classes for loading the asset using asset type specific code  virtual bool unload() = 0;  string resource_link_; // Might be a file, an URL, etc.private:  time_t last_accessed_; // Last time of access, used for memory management.  bool loaded_; // True when loaded.};class texture_asset : public asset{public:  texture_asset( const string & res );  virtual ~texture_asset();  char * get_raw_texture(); // Example of an unrelated derived behaviorprotected:  virtual bool load();  virtual bool unload();};int someFunc(){  // The reason why you could not get a texture_asset pointer from an asset   // pointer is just because it is an upcast, dynamic_cast<> can help you,  // it normally throws an exception when the type is incompatible, RTTI must  // be enabled to use this  texture_asset * a = dynamic_cast< texture_asset * >( manager.get_asset( "TEX01.TGA" ) );  // Since you know that your asset of ID TEX01.TGA will be a texture, the cast shoul be successful}


Hope this helps you out.

This topic is closed to new replies.

Advertisement