我可以在不使用点运算符的情况下访问结构内部的结构吗?

Posted

技术标签:

【中文标题】我可以在不使用点运算符的情况下访问结构内部的结构吗?【英文标题】:can I access a struct inside of a struct without using the dot operator? 【发布时间】:2010-05-10 23:31:45 【问题描述】:

我有 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;

有没有办法做这样的事情。这样做的原因是,如果发生对结构的更改,我希望保持数据的完整性,并且不要重复自己,也不必更改我现有的代码,也不要让字段嵌套得太深。

已解决:感谢您的所有回答。这样做以便我可以使用自动完成的最后一种方法如下:

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

【问题讨论】:

你的代码对我来说是零意义的。 str3 不是类型,而是对象。声明str3 str 毫无意义。当你声明结构时,说struct str3 ... ; 而不是struct ... str3; 这就是为什么你没有找到答案,但其他人都找到了。 来自***:typedef 是 C 和 C++ 编程语言中的关键字。 typedef 的目的是为现有类型分配替代名称。来自我:我猜它毕竟是一种类型,这取决于姜黄。 你在哪里看到 typedef?您上面的代码创建了两个匿名类型,并为它们创建变量 str1 和 str2 实例(然后对 str3 再次执行相同操作)。如果您要尝试攻击评论者,至少要让您的事实正确。 人们对您的主题做出反应的“攻击”是怎么回事? @Wilhelm/dash/Maciej 【参考方案1】:

是的。而是使用 C 风格的继承,使用 C++ 风格:

struct str3
  int a;
  int b;
  int c;
;

struct str2 : public str3
  object2 name;
;

【讨论】:

它可以工作,但现在如果我使用自动完成功能,Qt 不会向我建议这些字段,也许如果我重新启动 qt 或从头开始重建或... 我在你的帖子中没有看到任何关于 Qt 的内容。 我冒昧地猜测,在您的资源至少得到最低限度的保存之前,Qt 不会重新生成它的自动完成信息。我不能肯定地说,因为我不使用 Qt。 (而且我认为 Qt 是一个库集,而不是一个 IDE?)我可以告诉你,鉴于上面的代码,这将编译(假设没有奇怪的 #define's): str2 foo; foo.a = 1; foo.b = 2; foo.c = 3; foo.name = "酒吧"; /* 抱歉格式不好,不能在评论中发布多行格式的代码? */ 我猜他指的是QtCreator。 @Georg @yan:在答案之后添加随机细节通常意味着您需要一个新问题,或者它应该存在。【参考方案2】:

第一句话。这个

struct

  int a;
  int b;
  int c;
 str3;

定义一个对象 str3,而不是类型 str3。

你可以使用继承来实现你想要的,但我建议改变你的结构的数量

struct str1

  int a;
  int b;
  int c;
;


struct str2 : public str1

  object1 name;
;  

【讨论】:

只是再次跟进-这里创建的类型的名称是什么?它不是您从帖子中所想的“str3”。 @Yan:不,你不能像以前那样。您的示例创建未命名类实例 @Yan: #1 是 Microsoft 扩展并定义一个 匿名实例 并为此使用类型名称,#2 确实提供了一些 IDL具体的事情,IDL 基本上是一种不同的语言。在标准 C++ 中,struct x; 定义了一个匿名类类型的实例。 试试吧,你会看到,我刚刚查找了一些可以做到这一点的 c 代码,它来自一位在这方面工作了 25 年的嵌入式工程师,他的工作被 NASA 使用 @Yan:我不知道你的编译器作为 standard C++ 的扩展做了什么,但我的说例如"'str3' does not name a type" 使用您问题中的代码。仅仅因为一个编译器允许它并不意味着它在标准中。如果您仍有疑问,请提出相关问题。【参考方案3】:

这样做的原因是如果结构发生变化,我想保持数据的完整性

为了实现这一点,我宁愿使用适当的封装、访问器和继承来使布局更改对用户代码不可见:

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_; 
;

【讨论】:

@GMan:呃,它一定是一夜之间长大的——但我现在什至收到了@ 通知;)【参考方案4】:

我不确定 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;

【讨论】:

如果我不需要在另一个结构中重用该结构,这将起作用【参考方案5】:

不要使用愚蠢的技巧来避免适当的重构。它会为您节省一点打字时间,但它会咬住您的……稍后。如果编辑起来那么复杂,那么您使用了错误的工具和/或您的命名方案不正确(很难找到/替换 1 个字母的名称)。

【讨论】:

【参考方案6】:

您可以使用 GCC 来执行此操作,就像其他海报 mentioned 一样,但除此之外,您还可以使用 -fms-extensions 标志,该标志允许您使用之前定义的 struct 作为未命名字段。

更多here.

【讨论】:

以上是关于我可以在不使用点运算符的情况下访问结构内部的结构吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不知道名称的情况下访问结构成员?

Git 可以在不丢失历史记录的情况下重组我的文件夹吗?

如何在不使用复制或克隆的情况下克隆Rust中的结构?

我可以在不使用 useState 的情况下访问 useEffect 中的变量吗?

可以在不使用内联绘图的情况下远程访问 IPython Notebook 吗?

记录一个常犯的错误:直接访问数据结构内部的数组