2010-05-10 36 views
3

我有2個結構,其90%的領域相同。我想將這些字段分組在結構中,但我不想使用點運算符來訪問它們。原因是我已經用第一個結構編碼並剛創建第二個結構。我可以在不使用點運算符的情況下訪問結構體內的結構嗎?

前:

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

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

現在我將創建第三個結構:

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

,並會改變str1和ATR2這樣:

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

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

最後,我想能夠通過這樣做訪問a,b和c:

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

,而不是:

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

有沒有辦法做這樣的事情。這樣做的原因是我想保持數據的完整性,如果發生結構變化,不要重複自己,也不必更改我現有的代碼,也沒有嵌套太深的字段。

已解決:thx爲你所有的答案。的做,這樣我可以使用自動完成最後的辦法也是以下:

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

+3

你的代碼對我來說毫無意義。 'str3'不是一個類型,它是一個對象。 'str3 str'這個聲明是沒有意義的。當你聲明結構時,說'struct str3 {...};'而不是'struct {...} str3;' – wilhelmtell 2010-05-10 23:40:25

+1

這就是爲什麼你沒有找到答案,但其他人做的。 – 2010-05-11 00:12:15

+0

來自wikipedia:typedef是C和C++編程語言中的關鍵字。 typedef的目的是爲現有類型分配替代名稱。 從我:我想這畢竟是一種類型,取決於情況。 – 2010-05-11 00:24:44

回答

10

是。而是使用繼承的C-風格,採用C++風格:

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

struct str2 : public str3{ 
    object2 name; 
}; 
+0

哦,當然,thx。 – 2010-05-10 23:40:32

+0

它的工作原理,但現在如果我使用自動完成功能,Qt不會向我建議這些字段,也許如果我重新啓動qt或從頭開始重建或... – 2010-05-10 23:49:58

+0

我在您的文章中沒有看到有關Qt的任何信息。 – GManNickG 2010-05-10 23:57:31

2

之所以這樣做,這是我要保持數據的integrety如果chnges到結構都發生

爲了實現這個目標我寧願使用適當的封裝,存取和繼承,以使佈局的變化從用戶代碼中不可見:

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_; } 
}; 
+0

@Downvoter:謹慎解釋? – 2010-05-11 00:39:55

+0

你的名字,它更長! – GManNickG 2010-05-11 07:19:31

+0

@G Man:呃,它一定是長了一夜 - 但我現在甚至得到'@'通知;) – 2010-05-11 12:16:09

3

第一個的話。 This

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

定義了一個對象str3,而不是一個str3類型。

你可以實現你想要使用繼承,但我建議改變你的結構的數量

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


struct str2 : public str1 
{ 
    object1 name; 
}; 
+0

只是再次跟進 - 這裏創建的類型的名稱是什麼?這不是'str3',因爲你似乎認爲你的帖子。 – 2010-05-11 00:34:33

+0

@Yan:不,你不能這樣做。您的示例創建* unnamed類*的*實例*。 – 2010-05-11 00:51:19

+0

http://msdn.microsoft.com/en-us/library/z2cx9y4f.aspx – 2010-05-11 02:19:33

1

我不知道C++(我還在學習C++),但在C,一些編譯器允許匿名結構。使用GCC 4.3時,如果未指定標誌,則編譯時無錯誤,但無法使用-ansi-std=c99進行編譯。它與然而-std=c++98成功編譯:


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; 
}
+0

這將工作,如果我不需要在另一個重用結構 – 2010-05-11 00:30:06

0

不要使用愚蠢的技巧,以避免適當的重構。它可以節省你一些打字的時間,但它會在你稍後的時間內咬人。如果編輯起來很複雜,那麼你是在使用錯誤的工具和/或你有一個錯誤的命名方案(1個字母的名字很難找到/替換)。

0

你可以用GCC做到這一點,因爲其他海報mentioned,但除了這一點,你可以使用-fms-extensions標誌,使您可以使用前面定義struct爲未命名字段。

更多here

相關問題