Archived

This topic is now archived and is closed to further replies.

Damocles

a class variable

Recommended Posts

I feel like I should know how to do this, but I seem to be missing part of the puzzle.... I want to make a variable that is of type class. I don''t mean a pointer to a class or instance, but a variable which contains a type of class. And if possible, to make it so the class variable is only of type A or anything derived from A. so I''m thinking maybe something like: class MyClassVar; would make a class variable, but how could I force it to be only type A and below? And can I use this class variable for instantiating other objects? eg: ClassTypeA ObjectA = new MyClassVar; Is this sort of thing possible?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Damocles
I want to make a variable that is of type class. I don''t mean a pointer to a class or instance, but a variable which contains a type of class. And if possible, to make it so the class variable is only of type A or anything derived from A.



You can''t. It must be a pointer. How much space must be allocated for the variable? Because it could be any subtype of A, you cannot know. Any class derived from A will be at least as large as A, but might be larger. The C++ compiler cannot allocate an unknown amount of space except at runtime. As soon as you allocate memory at runtime, you are in the world of pointers.


quote:
Original post by Damocles
so I''m thinking maybe something like:

class MyClassVar;

would make a class variable, but how could I force it to be only type A and below? And can I use this class variable for instantiating other objects? eg:

ClassTypeA ObjectA = new MyClassVar;

Is this sort of thing possible?



Judging from your suggestion, I''m guessing that you are a VisualBasic programmer (although I might be wrong). FYI, objects in VB are actually just pointers to real objects. What you want, what you need, in this case is a pointer to an object. There is no other choice in the matter. Well, there might be: you might be able to get away with a reference, but it depends upon certain restrictions. And a reference is *essentially* a pointer that uses different syntax.

Share this post


Link to post
Share on other sites
What is the end goal that you''re trying to accomplish? It sounds like you''re asking about base class and inheritance. If you use a base class and derive from it, you can do things like this:


  
class A {};
class B : public A {};
class C : public B {};
class D {};

int main(int argc, char* argv[])
{
A *pA = new A();
B *pB = new B();
C *pC = new C();
D *pD = new D();

A *pTemp = NULL;
pTemp = dynamic_cast<A*>(pA); // This is ok

pTemp = dynamic_cast<A*>(pB); // This is ok

pTemp = dynamic_cast<A*>(pC); // This is ok

pTemp = dynamic_cast<A*>(pD); // This will set pTemp to NULL

// to indicate that pD is not an instance of a class

// derived from ''A''

}


You can assign a pointer of a class to point to any of its base classes, but dynamic_cast will return NULL if you try to cast a pointer to a type that it isn''t derived from.

If this doesn''t answer your question, try explaining what you''re trying to do and we''ll see if we can figure something out.

Share this post


Link to post
Share on other sites
Hmm...ahah! I think I understand what you want now. You probably want some kind of a class factory, a mechanism for producing objects of a type determined at run-time instead of at compile-time. Let me know if this is incorrect.

To create a class factory, you will need some way of identifying the class other than the class name. Let''s say you use an integer ID and assign one ID number to each of the classes that can be created. You will also need a class that handles the association of classes to these IDs, so that you can call a function to create a class from its ID without actually specifying the class name in your code.

Here''s a brief example of a factory using the standard library map class.


  
// Include the appropriate standard library headers.


# include <iostream>
# include <map>

using namespace std;

// Create a base class that defines the foo interface.


class foo {};

// Create the derived foo_X types that perform the actual work

// for the foo interface.


class foo_A : public foo {};
class foo_B : public foo {};
class foo_C : public foo {};

// Make some numeric constants to hold our foo_X type information


enum foo_type { A=1, B=2, C=3 };

// Define a function pointer type for the functions that create foo''s.


typedef foo* (*foo_creator) ();

// Now for the foo factory, which will manage all of this.


class foo_factory
{
public:
foo_factory () {}
~foo_factory () {}

void register (foo_type type, foo_creator creator) { creators [type] = creator; }

foo* create (foo_type type) { creators [type] (); }

void destroy (foo* p) { delete p; }

private:
map <foo_type, foo_creator> creators;
};

// Now define the foo creation functions used by the factory. This

// is where the real magic occurs. The function pointers become

// like "objects" that we use to create new foo''s at whim!


inline foo* foo_A_creator () { return new foo_A; }
inline foo* foo_B_creator () { return new foo_B; }
inline foo* foo_C_creator () { return new foo_C; }

// Now, to demonstrate the power of foo!


int main ()
{
// Create a foo factory.


foo_factory factory;

// Register the foo''s that the factory can create.


factory.register (A, &foo_A_creator);
factory.register (B, &foo_B_creator);
factory.register (C, &foo_C_creator);

// Use the factory to create and destroy the foo''s.


foo* f1 = factory.create (A);
foo* f2 = factory.create (B);
foo* f3 = factory.create (C);

factory.destroy (f1);
factory.destroy (f2);
factory.destroy (f3);

// Now create and destroy the foo desired by the user!


int desired_type = 0;

cout << "Create which foo type? (1-3) ";
cin >> desired_type;

foo* f = factory.create (desired_type);

factory.destroy (f);

// Ah, sweet success!


cout << "Foo creation was successful!" << endl;
}


Is that what you wanted to do?

If you need more explanation let me know.

Share this post


Link to post
Share on other sites