Skip to main content
gamedev.net
🔒 Locked

dynamic object usage?

Started by rgirard413 7 replies 1.2k views
Original Post
rgirard413
rgirard413
I couldn't seem to figure out how to do this. basically i have two classes(a and b, both of which share same function names, but may have different variables.). what im trying to do is, based on a separate value, call one or the other classes. ie.

Class A
{
public:
    int x();
private:
    float somevalue;
};

Class B
{
public:
    int x();
private:
    int someothervalue;
}

main()
{
     psuedo - enter some value, if its a 1, use class A, if its a B, use class b

     //(class) has to be dynamic as to avoid using switches or if statements
     // all the time. regardless of hte value i enter, ill always use
     // (class) as the object.
     (class).x();
}
Is this something that would be achived through inheritence? Any help would be great.
http://www.thedizzle.com
Xai
Xai
for that you would use a common base class with a virtual function. Lookup up "runtime polymorphism" and "virtual functions" or something like that.
Zahlman
Zahlman
class Parent {  public:  virtual int x() = 0;  virtual ~Parent() {}};class A : public Parent {  public:  // do NOT redeclare x() here  private:  float somevalue;};class B : public Parent {  public:  private:  int someothervalue;}// implement A::x() and B::x()int main() {  // in C++, main() MUST return int, and you MUST explicitly write 'int'  // for the return type.  int which;  // pseudo: input which  Parent* p;  // In cases where the thing in question doesn't exist yet AND its exact type  // isn't known, we will have to instantiate it dynamically:  if (which == 0) { p = new A(); }  else { p = new B(); }  p->x();  // Because Parent declared x() to be 'virtual', this will decide at runtime  // which x() to use. You must have a pointer OR REFERENCE to get this kind  // of "polymorphic" behaviour.  delete p; // You can also avoid this cleanup by making proper use of the  // standard library class "std::auto_ptr".}
rgirard413
rgirard413
is there a way i can pass say a value to p to have it determine which to use like:


Parent *p = new Parent(which);

if which is 0 it will automatically use A, otherwise B?
http://www.thedizzle.com
Enigma
Enigma
You can use a static member function (or even a free function) to encapsulate the choice. Then instead of calling new you call your static member function, which uses new to create the appropriate instance and returns it to you (I'll also demonstrate the use of auto_ptr, though the same technique is equally applicable when working with raw pointers):

#include <stdexcept>#include <memory>class Parent{	public:		virtual int x() = 0;		virtual ~Parent() {}		// static member function which encapsulates creation		static std::auto_ptr< Parent > create(int which);};class A	:	public Parent{	public:		// certainly DO redeclare x here, otherwise you won't be able		// to instantiate your class!		virtual int x();	private:		float somevalue;};class B	:	public Parent{	public:		virtual int x();	private:		int someothervalue;};// implement A::x() and B::x()// static member function which encapsulates creation - implementationstd::auto_ptr< Parent > Parent::create(int which){	if (which == 0)	{		return std::auto_ptr< Parent >(new A());	}	else if (which == 1)	{		return std::auto_ptr< Parent >(new B());	}	else	{		throw std::runtime_error("invalid choice");	}}int main(){	int which;	// pseudo: input which	std::auto_ptr< Parent > p = Parent::create(which);	p->x();}

Σnigma
Zahlman
Zahlman
Enigma has it. He's also correct about the redeclaration (I had a brainfart and got confused with the behaviour of redeclared data members).
rgirard413
rgirard413
thanks a lot guys, this was actually my way of creating a dynamic allocating graphics driver(dx vs gl) so that the user can specify which they want to use and i wont have to change the rest of my code :)
http://www.thedizzle.com
rgirard413
rgirard413
is there a way in to addition of doing this that i can access the functions of the driver individually without using virtual functions. So say i declare p as new a();

std::auto_ptr< Parent > p = Parent::create(which);
p->x();

but then i can do something like:

p->CreateVertexBuffer(params...); if i am using the dx driver

or

p->whateveropengl'sfunctionis(params...);

Essentially I wont want to have to declare virtuals for EVERY function...
http://www.thedizzle.com
Extrarius
Extrarius
The most common method to do what you want is:
A *pA;B *pB;if((pA = dynamic_cast(p)) != NULL) {/*Use pA*/}else if((pB = dynamic_cast(p)) != NULL) {/*Use pB*/}else {/*Error*/}
If you don't want to actually use type-specific stuff but want to know which type it is, you can do:
#include <typeinfo>if(typeid(*p) == typeid(A)) {/*'real' type is A*/}else if(typeid(*p) == typeid(B)) {/*'real' type is B*/}else {/*Error*/}

Note that doing this pretty much completely breaks the point of using polymorphism - you want to be able to use A and B as if they were the some. The only class-specific functions you should have should be private utility functions that help to implement the more abstract methods.

[Edited by - Extrarius on August 9, 2006 2:20:05 PM]
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.