tags:

views:

274

answers:

6

I have 2 structures that have 90% of their fields the same. I want to group those fields in a structure but I do not want to use the dot operator to access them. The reason is I already coded with the first structure and have just created the second one.

before:

typedef struct{
  int a;
  int b;
  int c;
  object1 name;
} str1;  

typedef struct{
  int a;
  int b;
  int c;
  object2 name;
} str2;

now I would create a third struct:

typedef struct{
  int a;
  int b;
  int c;
} str3;

and would change the str1 and atr2 to this:

typedef struct{
  str3 str;
  object1 name;
} str1;

typedef struct {
  str3 str;
  object2 name;
} str2;

Finally I would like to be able to access a,b and c by doing:

str1 myStruct;
myStruct.a;
myStruct.b;
myStruct.c;

and not:

myStruct.str.a;
myStruct.str.b;
myStruct.str.c;

Is there a way to do such a thing. The reason for doing this is I want keep the integrety of the data if chnges to the struct were to occur and to not repeat myself and not have to change my existing code and not have fields nested too deeply.

RESOLVED: thx for all your answers. The final way of doing it so that I could use auto-completion also was the following:

struct str11
{
int a;
int b;
int c;
};
typedef struct str22 : public str11
{
QString name;
}hi;

+9  A: 

Yes. Rather using a C-style of inheritance, using C++ style:

struct str3{
  int a;
  int b;
  int c;
};

struct str2 : public str3{
  object2 name;
};
Nathan Ernst
oh yes of course, thx.
yan bellavance
it works but now if I use the autocompletion feature, Qt does not suggest these fields to me, maybe if I restart qt or rebuild from scratch or...
yan bellavance
I don't see anything about Qt in your post.
GMan
I'd hazard a guess that until your sources have at least minimally been saved, Qt is not going to regenerate it's autocomplete info. I can't say for certain as I don't use Qt. (And I thought Qt was a library set, not an IDE?)I can tell you that given the above code that this will compile (assuming no strange `#define`'s): str2 foo; foo.a = 1; foo.b = 2; foo.c = 3; foo.name = "bar";/* sorry for the bad formatting, can't post multi-line formatted code in a comment? */
Nathan Ernst
I guess he is referring to QtCreator.
Georg Fritzsche
yes i'm referring to QtCreator.
yan bellavance
@Georg @yan: The point being adding random details after the answer often means you need a new question or it should have been there to being with.
GMan
+2  A: 

The reason for doing this is I want keep the integrety of the data if chnges to the struct were to occur

To achieve that i'd rather use proper encapsulation, accessors and inheritance to make changes in layout invisible from user code:

class DataHolder {
    int a_, b_, c_;
public:
    int a() const { return a_; }
    int b() const { return b_; }
    int c() const { return c_; }
};

class User : public DataHolder {
    object o_;
public:
    object& getObject() { return o_; }
};
Georg Fritzsche
@Downvoter: Care to explain?
Georg Fritzsche
Your name, it is longer!
GMan
@GMan: Uh, it must have grown over night - but i even get `@` notifications now ;)
Georg Fritzsche
+3  A: 

First one remark. This

struct
{
  int a;
  int b;
  int c;
} str3;

defines an object str3, not a type str3.

You can achieve what You want using inheritance, but I suggest changing the numbers of Your structs

struct str1
{
  int a;
  int b;
  int c;
};


struct str2 : public str1
{
  object1 name;
};  
Maciej Hehl
Just to follow up again- what is the name of the type being created here? It is not 'str3' as you seem to think from your posts.
dash-tom-bang
@Yan: No, you can't the way you did. Your examples create *instances* of an *unnamed class*.
Georg Fritzsche
http://msdn.microsoft.com/en-us/library/z2cx9y4f.aspx
yan bellavance
http://idlastro.gsfc.nasa.gov/idl_html_help/Structure_Variables.html
yan bellavance
@Yan: #1 is a Microsoft extension and *defines* an *anonymous instance* and uses a type name for that, #2 does presents some IDL specific things, with IDL basically being a different language. In standard C++, `struct {} x;` defines an instance of an anonymous class type.
Georg Fritzsche
try it you will see, I just looked up some c code that does it and its from an embedded engineer who has been working in this for 25 years and who's work is used by NASA
yan bellavance
@Yan: I don't know what your compiler does as an extension over *standard* C++, but mine says e.g. *"'str3' does not name a type"* with the code in your question. Just because one compiler allows it doesn't mean that its in the standard. If you still have doubts open a question about it.
Georg Fritzsche
@yan: this cracked me up "from an embedded engineer who has been working in this for 25 years and who's work is used by NASA". Doesn't matter who creates it, even if he's 25 year working at NASA (that does more harm than good). Crappy code will always be crappy code.
PoweRoy
@of course you need to put the typedef there for it to compile but you can certainly grasp the concept of what im trying to say without having to put it.
yan bellavance
+1  A: 

I'm not sure about C++ (I'm still learning C++) but in C, some compilers allow anonymous structs. With GCC 4.3, the following compiles with no errors when no flags are specified, but fails to compile with -ansi or -std=c99. It compiles successfully with -std=c++98 however:


int main (int argc, char *argv[])
{
    struct
    {
        struct
        {
            int a;
            int b;
            int c;
        };
        int test;
    } global;

    global.a = 1;
    global.b = 2;
    global.c = 3;
    global.test = 4;

    return global.b;
}
dreamlax
this would work if I didnt need to reuse the struct in another one
yan bellavance
A: 

Don't use silly tricks to avoid proper refactoring. It will save you a little bit of typing but it will bite in your a.. later. If it is that complicated to edit, then you're a using the wrong tools and/or you have a bad naming scheme (1 letter names are difficult to find/replace).

tristopia
A: 

You can do it with GCC, as other poster mentioned, but in addition to this you can use -fms-extensions flag that allows you to use earlier defined struct as unnamed field.

More here.

qrdl