• Advertisement
Sign in to follow this  

Assigning a struct to a class

This topic is 4272 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

How exactly would you go about assigning a struct to a class? Example: struct SimpleStruct { int data; int moredata; } class MyStructClass { int data; int moredata; } SimpleStruct struct; MyStructClass object; struct = object; The assignment operator can only be overloaded in a class and it's always the left hand operand. So how can make something like this work?

Share this post


Link to post
Share on other sites
Advertisement
Since a "class" is availible you must be using C++...

Structs in C++ are the same as classes, only their default protection is public, not private.

Anyways, you can't just assign different classes/structs to each other. You must define an operator for it:

class b {
public:
int i;
};

struct a {
int i;

a &operator =(const b &o) {
i = o.i;
return *this;
}
};

b B;
a A;
A = B;


Same goes the other way.

Share this post


Link to post
Share on other sites
Thanks for your reply but..

I failed to explain my whole situation (for this I apolagize).

Yes I am working with C++, and I neglected to mention that the struct is one from an API so I don't have access to modify it so adding an overloaded operator to it is not an option.

Again sorry for the lack of detail.

Share this post


Link to post
Share on other sites
Quote:
Original post by SirSmokey
Thanks for your reply but..

I failed to explain my whole situation (for this I apolagize).

Yes I am working with C++, and I neglected to mention that the struct is one from an API so I don't have access to modify it so adding an overloaded operator to it is not an option.

Again sorry for the lack of detail.


Make a function to do it for you.

void assign( API_Bar &bar, const Foo &foo )
{
bar.member = foo.member;
}

I'm pretty sure you cannot make it so that it is avaiable as an operator overload without modifing the source.

Share this post


Link to post
Share on other sites
You could always create a wrapper class that contains the original struct and passes along regular calls to it, handling any special ones in the wrapper.

Share this post


Link to post
Share on other sites
Couldn't you just add a global overloaded operator?



SimpleStruct& operator=(SimpleStruct& s, MyStructClass& c)
{
s.data = c.data;
s.moredata = c.moredata;
}



Any particular reason why you couldn't just add that into your own code? I'm assuming that's the only place it will be used.

Share this post


Link to post
Share on other sites
Endar: YOu can't overload the assignment operator outside of a class and since the "SimpleStruct" isn't part of my code but a struct from an API I can't modify it.

Share this post


Link to post
Share on other sites
You might want to consider the function or the wrapper method.
For the wrapper method, you might want to use "operator Wrapper::API_X*()" and "operator Wrapper::API_X&()" (though I'm not entirely sure if the latter will work).

Share this post


Link to post
Share on other sites
You can inherit from their struct and just add functions without adding any data members.

Share this post


Link to post
Share on other sites
You could use something like the following if your struct and class have the exact same members in the exact same order, or maybe if the first few members of your struct are the exact same as the entire class.

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

#define P(t) std::cout << t
#define I(v) std::cin >> v
#define transferdata(target, source) memcpy(&target, &source, sizeof(source));

class cvar
{
public:
int a;
float b;
};

typedef struct
{
int a;
float b;
}svar;

int main()
{
cvar v1; // our class
svar v2; // our struct
v1.a = 2; // set the values of our class
v1.b = 3.0f;
transferdata(v2, v1); // transfer data from our class to our struct
P(v2.a); // display a variable from our struct. Answer should be 2.
getch(); // wait for a keypress
return 0;
}


Share this post


Link to post
Share on other sites
Quote:
Original post by Promit
You can inherit from their struct and just add functions without adding any data members.


This would be my recommendation.

Share this post


Link to post
Share on other sites
I'm going along on the inheritance bandwagon, but it's almost criminal that nobody mentioned friend functions.


struct TheirStruct
{
int a, b;
};

class CMyClass
{
int a, b;
CMyClass& operator=(const TheirStruct& rval);
friend TheirStruct& operator=(TheirStruct& lval, const CMyClass& rval);
};




[Edited by - templewulf on May 8, 2006 12:44:17 PM]

Share this post


Link to post
Share on other sites
I'm surprised by the lack of mention of friend functions also. Is there a good reason to go the inheritance route instead?

Share this post


Link to post
Share on other sites
First, the problem is not that one is a struct and the other is a class. Even if they were both classes or both structs, it wouldn't work. The problem is that the types are different.

  1. Why do you have a new class MyStructClass that is the same as SimpleStruct? Couldn't you just use SimpleStruct? If they are the same type, then the assignment will work.
  2. Instead of inheritance, MyStructClass could contain an instance of SimpleStruct. But it depends on what MyStructClass represents. Something like this:
        struct SimpleStruct
    {
    int data;
    int moredata;
    };

    class MyStructClass
    {
    SimpleStruct s;
    ... more stuff ...
    };

    SimpleStruct simple;
    MyStructClass object;

    simple = object.s;

Share this post


Link to post
Share on other sites
Those are some great ideas. But I think I'm gonna have to give away more info on specific problem here.

The API struct is from the Win32 API, CHAR_INFO. This struct holds info about a character cell in a console buffer like its fore and back color and is character. The API function WriteConsoleOutput takes an array of CHAR_INFOs and dumps them all to the screen at once. However CHAR_INFO is a little difficult to work with because there is no comparison operator, the fore and back color are a WORD with the low (I think it's the low byte, the first 4 bits on the right?) being the forecolor and the last being the back color. So to change the fore or back color individually you have to go through some bit manipulation stuff that's ugly. The other thing is I wanted to add functionality and some more information about cells, like a flag to set the cell visible or not and some comparison operators.

So I wanted to be able to work with Cell objects then when it was time to write them to the screen I could simply loop through my array of Cell objects and create the needed array of CHAR_INFOs by saying "CharInfo[i] = CellObeject[i]"

I guess the best solutions is, as stated above, give Cell a CHAR_INFO member and just use that.

Thanks for all the replies, I was just looking for a cleaner way for doing it but this will work.

Thanks again!

Share this post


Link to post
Share on other sites
Ok sorry but I had another thought:

If I do inherit the Cell class from CHAR_INFO and I have a vector of Cell objects and vector of CHAR_INFO objects, is there a way I can up cast the Cell vector to a CHAR_INFO so I can just assign the one vector to the other?

Like:

vector<CHAR_INFO> CharVec;
vector<Cell> CellVec;

CharVec = (CHAR_INFO)CellVec;

I know this doesn't work because I get a compiler error: " error C2440: 'type cast' : cannot convert from 'std::vector<_Ty>' to 'CHAR_INFO'
with
[
_Ty=Cell
]
"

Is there a way to do this that I am unaware of?

Share this post


Link to post
Share on other sites
Even though I suggested something other than inheritance, after seeing your description it is apparent that inheritance is the proper way to do it.

You have to assign the elements one at a time because the the arrays contain different types and the elements have to be converted individually. For example (assuming Cell is derived from CHAR_INFO):
    for ( int i = 0; i < CharVec.size(); ++i )
{
CharVec[i] = CellVec[i];
}

Share this post


Link to post
Share on other sites
Quote:
Original post by JohnBolton
Even though I suggested something other than inheritance, after seeing your description it is apparent that inheritance is the proper way to do it.

You have to assign the elements one at a time because the the arrays contain different types and the elements have to be converted individually. For example (assuming Cell is derived from CHAR_INFO):
    for ( int i = 0; i < CharVec.size(); ++i )
{
CharVec[i] = CellVec[i];
}


Uh, doesn't std::copy respect polymorphism?


std::copy(CellVec.begin(), CellVec.end(), std::back_inserter(CharVec));


Share this post


Link to post
Share on other sites
Quote:
Original post by JohnBolton
Even though I suggested something other than inheritance, after seeing your description it is apparent that inheritance is the proper way to do it.

You have to assign the elements one at a time because the the arrays contain different types and the elements have to be converted individually. For example (assuming Cell is derived from CHAR_INFO):
    for ( int i = 0; i < CharVec.size(); ++i )
{
CharVec[i] = CellVec[i];
}


Quote:
Zahlman
Uh, doesn't std::copy respect polymorphism?

std::copy(CellVec.begin(), CellVec.end(), std::back_inserter(CharVec));


Thanks to the both of you for your replies. std::copy looks to be the best answer, but I am curious, is there any advantage of using std::copy instead of looping through bother vectors like JohnBolton suggested?

Share this post


Link to post
Share on other sites
std::copy:

- is less error prone once you know how to use it, because it
- avoids the need for a separate counter variable (which both clutters the abstraction with an irrelevant thing - you just want to say "copy everything in this range"; why should you have to think about your progress? - and offers the chance to write something incorrect, especially if you have nested loops).
- can protect you from code changes if you later change the container type (to be fair, using a manual iterator loop rather than an index loop can do this as well).
- can apply optimizations automatically if you later change the container type (especially to an array - although in that case you're not insulated quite as well against code changes, because you can't .begin() or .end() an array).

:)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement