Click to See Complete Forum and Search --> : Structures and Classes


Joerg Nowak
April 26th, 1999, 07:57 PM
How does one create a class that uses the elements of a structure as its elements?

In specific, I have a structure that contains a number of elements, that I need to be able to use without changing the structure. However I also want to use the elements of the structure and serialize it and ultimately I want to phase out the structure, therefore I would like to be able to substititute a class wherever the structure is required.

This type of approach is taken by the CRect class and Rect Structure and the CPoint class and Point structure. Could someone please explain how the elements of the structure were made public elements of the class. Any help is appreciated.

Thanks

Paul McKenzie
April 26th, 1999, 09:04 PM
The trick is to enclose an instance of the structure within the class, and supply casting operator that returns a pointer to the struct as well as the struct itself.

For example if you have legacy code that looks like this:

struct {
...
} MYSTRUCT;

and a legacy function prototyped like this:
void Foo(MYSTRUCT *p) {}
void Foo2(MYSTRUCT s) { }

You would create a class like this

CMyStruct {
private:
struct mystruct m_Instance;
public:
operator MYSTRUCT *() { return m_Instance; }
operator MYSTRUCT() { return m_Instance; }
};

Anywhere where you need a MYSTRUCT* or MYSTRUCT, you can supply the object, and the cast operator does it's magic:

CMyStruct TestStruct;
Foo(TestStruct); // Pointer version
Foo2(TestStruct); // Struct version

The compiler knows which cast to perform (or at least it should know).

Regards,

Paul McKenzie.

Dave Lorde
April 27th, 1999, 10:20 AM
It depends; you can either embed your structure in a wrapper class as Paul suggested, or you can derive a new class from it, or you can keep it as it is and just add functions to it.

[Remember, a struct *is* just a class with default public access, so it can have functions and can declare private/protected members]

1. Derive a new class:

struct OldStruct
{
int data_1;
int data_2;
};

// OldStruct contents become public members of MyNewClass
class MyNewClass : public OldStruct
{
public:
ostream& Serialize(ostream& os) {
os << data_1 << data_2;
return os;
}
};
If you want the OldStruct contents to become private members of MyNewClass, inherit it as private - "class MyNewClass : private OldStruct". You will then need to give it functions to get and set the data values.


2. Alternatively just extend the OldStruct with new functions, constructors, etc.:

struct OldStruct
{
int data_1;
int data_2;

ostream& Serialize(ostream& os) {
os << data_1 << data_2;
return os;
}
};

If you want to change the OldStruct data to have private access, just add the access specifiers:

struct OldStruct
{
private:
int data_1;
int data_2;
public:
ostream& Serialize(ostream& os) {
os << data_1 << data_2;
return os;
}
};

Of course, by now OldStruct looks more like a class than a struct, so you might consider changing it to a class (replace 'struct' with 'class'):

class OldStruct
{
private:
int data_1;
int data_2;
public:
ostream& Serialize(ostream& os) {
os << data_1 << data_2;
return os;
}
};

The change from 'struct' to 'class' only changes the default member access to private from public, nothing else. They are otherwise identical in form and function.

Hope this helps,

Dave

sally
April 27th, 1999, 08:43 PM
"This type of approach is taken by the CRect class and Rect Structure and the CPoint class and Point structure. Could someone please explain how the elements of the
structure were made public elements of the class. Any help is appreciated." holds the key

derive your new class from the struct

sally

Sally
April 27th, 1999, 08:43 PM
"This type of approach is taken by the CRect class and Rect Structure and the CPoint class and Point structure. Could someone please explain how the elements of the
structure were made public elements of the class. Any help is appreciated." holds the key

derive your new class from the struct

sally

April 27th, 1999, 09:17 PM
The best way is to derive a class from the structure. That way, all the members of the structure become public members of the class and you don't need casting operators like a wrapper class does. This is the way CRect, CPoint, and CSize work.

Joerg Nowak
April 28th, 1999, 01:28 PM
Thanks, I have a couple of questions however as it relates to deriving the class from a structure

First, how do I assign elements of a an existing structure to the class. I presume that one overloads the assignment operator, but all the samples that I've seen do assignment between one class object to another object of the smae type. Is it possible to do an assignment operator as follows const CMyClasst &operator=(const MyStruct &) additionally the structure is often reference by pointer, How would I set up an assignment operator for CMyClass to CMyStruct pointers?

Secondly, I need to use the Serialize function since I am passing the structure data across on a socket (which is the original reason for making the structure into a class) and it seems that I need to derive my new class from the CObject class in order to Serialize across a socket. Can I use the iostream Serailize function in a derived class or am I going to have to use a Wrapper Class as discussed by Paul McKensie which is derived from COject.

Thanks in advance for any help or advice