Archived

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

Void Pointer Class

This topic is 5172 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m working on a scripting engine and it stores variables using a Primitive Class. Now this class stores the value of the primitive as a void pointer, since a primitive can be an int, a double, or one of many data types. What I''d like to do, to make my life easier, is make an accessor method that returns an already dereferenced value of the primitive. So I could do something like this:
  Primitive x;
  // turns x into an int primitive and sets it to 5

  x = 5;
  // gets the dereferenced value of x (which is 5) and prints it to the screen

  std::cout << x.getValue() << endl;
As it is, if I want to print out the number 5 to the screen I need to do this:
  std::cout << *(int*)x.getValue() << endl;
That assumes I already know that x is an int, which I may or may not know. The source code for my Primitive Class is fairly simple and is as follows:
class Primitive {
public:
	Primitive() {
		type = -1;
		is_protected = false;
	}
	void operator=(bool newVal) {
		value = new bool(newVal);
		type = 0;
	}
	void operator=(char newVal) {
		value = new char(newVal);
		type = 1;
	}
	void operator=(short newVal) {
		value = new short(newVal);
		type = 2;
	}
	void operator=(int newVal) {
		value = new int(newVal);
		type = 3;
	}
	void operator=(long newVal) {
		value = new long(newVal);
		type = 4;
	}
	void operator=(float newVal) {
		value = new float(newVal);
		type = 5;
	}
	void operator=(double newVal) {
		value = new double(newVal);
		type = 6;
	}
	void operator=(CString newVal) {
		value = new CString(newVal);
		type = 7;
	}
	void operator=(char* newVal) {
		value = new CString(newVal);
		type = 7;
	}
	void* getValue() {
		return value;
	}
private:
	CString		name;				// name of primitive

	bool		is_protected;		// can the primitive be modified

	void*		value;
	int			type;
					// 0 bool

					// 1 char

					// 2 short

					// 3 int

					// 4 long

					// 5 float

					// 6 double

					// 7 string

};
So to simply my problem... is there a method I can make that automatically dereferences the value stored by the primitive so that I don''t have to dereference it myself? Any help is appreciated.

Share this post


Link to post
Share on other sites
Strictly for output, you could define a stream operator that would have a switch inside to output the data as its stored type. This would also eliminate the need for a getValue accessor as it related to I/O, as well.

I don''t have an answer for the general problem, though I have thought about it before.

Share this post


Link to post
Share on other sites
Thank you ZealousElixir, for output you''re right, I can indeed define a stream operator that checks what the type is and converts it automatically.

The pertinant issue, however, is that I need to assign actual ints, or doubles, or CStrings to the value being pointed to by my Primitive class so that the following would work:


Primitive x;
x = "Hello World!";
CString y;
y = x.getValue();

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites
quote:
Original post by Kranar
Thank you ZealousElixir, for output you''re right, I can indeed define a stream operator that checks what the type is and converts it automatically.

The pertinant issue, however, is that I need to assign actual ints, or doubles, or CStrings to the value being pointed to by my Primitive class so that the following would work:


Primitive x;
x = "Hello World!";
CString y;
y = x.getValue();


I can''t think of any way in which that could conceivably work. C++ allows overloading on the type and number of parameters, but not on the return type. Why can''t you use a stream operator, though? It would do the same thing:

Primitive x;
x = "Hello World!";
CString y;
x >> y;

Overload assignment operators, if you wish, by the parameter type (or use stream insertion operators for increased consistency), but I can''t see any simple and clean solution going the other way.

Share this post


Link to post
Share on other sites
Fruny: Don't Any and Variant still require some type of casting or visitation mechanism, making them cumbersome for the desired use?


To implement stream assignment (which seems bloody weird, but is the most elegant way I see), you might try something like this:

Primitive &operator >> (const Primitive &Rhs)
{
m_value = Rhs.m_value;
m_type = Rhs.m_type;
}

This assumes that there's a Primitive constructor that every possible type (or else you'll get a compile-time implicit conversion warning), and that I haven't done something flagrantly illegal. One other big concern comes when dealing with pointer types, but I assume since the class is named primitive that you're only dealing with non-pointers.


edit : Sadly, none of this works. In order to do a generic assign at run-time, you'd need type information.

I really don't have an understanding of the Any type, but perhaps there's a way to blend RTTI, one of those boost types, and what I've said above into some solution for this.
Then again, I could be spouting crap.

Later,
ZE.

[edited by - zealouselixir on October 13, 2003 11:03:12 PM]

Share this post


Link to post
Share on other sites

Primitive& operator>>(Primitive &p, int &i)
{
if(p.type == INT) // Pseudocode, but I do suggest using an enum for clarity

{
i = p->value;
return p;
}
else
// Some error notification; throw an exception?

}

Primitive& operator>>(Primitive &p, std::string &s)
{
if(p.type == STRING)
{
s = p->value;
return p;
}
else
// ...

}

... And so on, and so forth. This may contain some minor errors, and I didn''t even look up how exactly your represent your types, but it should give you the general idea. As an aside you should, of course, read up on overloading stream insertion and extraction operators.

Share this post


Link to post
Share on other sites
quote:
Original post by ZealousElixir
Fruny: Don't Any and Variant still require some type of casting or visitation mechanism, making them cumbersome for the desired use?



boost::any does - you have to tell it what type you want to extract from the variable :

any foo = 5;
int bar = any_cast(foo);


But boost::variant does not (IIRC).


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on October 13, 2003 11:38:36 PM]

Share this post


Link to post
Share on other sites