【问题标题】:initialize struct contain references to structs初始化结构包含对结构的引用
【发布时间】:2013-01-25 04:36:44
【问题描述】:

是否可以有一个包含对结构的引用的结构。这些是如何初始化的?请参阅下面的简短示例。

谢谢

typedef struct {
  int a;
}typeInner1;


typedef struct {
  int b;
}typeInner2;


typedef struct {
  typeInner1 &one;
  typeInner2 &two;
}typeOuter;

void fun2(typeOuter *p){
  p->one.a =2;
  p->two.b =3;
}


void fun(typeInner1 &arg1,typeInner2 &arg2){
  typeOuter *ptr = new typeOuter;//<-- how to write initializer
  fun2(ptr);
}


int main(){
  typeInner1 arg1;
  typeInner2 arg2;
  fun(arg1,arg2);

  //now arg1.a should be 2 and arg2.a=3
}

好的,感谢您的所有意见。我还必须修改 typeOuter 的 typedef 以使其工作。下面的完整工作代码供其他人找到这篇文章。

#include <cstdio>
typedef struct {
  int a;
}typeInner1;


typedef struct {
  int b;
}typeInner2;


typedef struct typeOuter_t {
  typeInner1 &one;
  typeInner2 &two;
  typeOuter_t(typeInner1 &a1, typeInner2 &a2) : one(a1), two(a2) {}
}typeOuter;

void fun2(typeOuter *p){
  p->one.a =2;
  p->two.b =3;
}


void fun(typeInner1 &arg1,typeInner2 &arg2){
  typeOuter *ptr = new typeOuter(arg1,arg2);
  fun2(ptr);
}


int main(){
  typeInner1 arg1;
  typeInner2 arg2;
  fun(arg1,arg2);

  //now arg1.a shoule be 1 and arg2.a=3
  fprintf(stderr,"arg1=%d arg2=%d\n",arg1.a,arg2.b);
}

【问题讨论】:

  • 顺便说一句,typedef struct {...} foo; 在 C++ 中不是“惯用的”,只是写 struct foo {...}; 更常见(并且可以让您直接使用 foo 作为类型名称)。

标签: c++ data-structures struct initialization


【解决方案1】:

typeOuter一个合适的构造函数:

struct typeOuter
{
  typeInner1 &one;
  typeInner2 &two;
  typeOuter(typeInner1 &a1, typeInner2 &a2) : one(a1), two(a2) {}
};



void fun(typeInner1 &arg1, typeInner2 &arg2) {
  typeOuter *ptr = new typeOuter(arg1, arg2);
  fun2(ptr);
}

【讨论】:

    【解决方案2】:

    在 C++ 中,您可以为 struct 创建一个构造函数。结构体基本上是使用public 作为默认访问修饰符的类。

    struct Example
    {
        // struct fields..
    
        Example(); // initialize struct objects.
        ~Example(); // perform clean up if necessary.
    };
    

    【讨论】:

      【解决方案3】:

      您的问题不在于引用structs,而在于一般初始化引用。引用不能被默认初始化,无论它们是对 struct 或内置类型的引用。

      int& x; // ERROR! Non-initialized reference to int
      C& y; // ERROR! Non-initialized reference to a struct C
      int z;
      C w;
      int& a = z; // OK: Initialized reference to int
      C& b = w; // OK: Initialized reference to struct C
      

      另一方面,当您的引用是 struct 的成员变量时(无论它们引用什么类型),它们必须在构造您的 struct 时立即绑定(就像常规引用一样)。默认构造您的struct,然后绑定引用不是一个选项,因为它分两步完成,并且在第一步之后引用将未初始化。

      因此,您必须为您的struct 提供一个构造函数,并在那里初始化您的引用:

      struct typeOuter {
        typeOuter(typeInner1& o, typeInner2& t) : one(o), two(t) { }
        typeInner1 &one;
        typeInner2 &two;
      };    
      

      您的 fun() 函数将如下所示:

      void fun(typeInner1 &arg1,typeInner2 &arg2){
          typeOuter *ptr = new typeOuter(arg1, arg2);
          fun2(ptr);
      }
      

      【讨论】:

        【解决方案4】:

        在 C++11 之前,您需要为您的结构 typeOuter 提供一个构造函数,并在初始化列表中初始化成员引用:

        typeOuter(typeInner1& i1, typeInner2& i2) : one(i1), two(i2) {}
        

        使用 C++11,您还可以选择直接使用初始化列表(无需自己定义构造函数):

        typeOuter *ptr = new typeOuter { arg1, arg2 };
        

        【讨论】:

          【解决方案5】:

          您可以添加构造函数,但也可以将聚合初始化与工厂函数一起使用。这适用于所有版本的 C++:

          struct A
          {
             int& i;
          };
          
          A make_a(int& i)
          {
             A a = {i};
             return a;
          }
          
          int main()
          {
             int i = 0;
             A* a = new A(make_a(i));
          }
          

          【讨论】:

            【解决方案6】:

            嗯..

            #include <cstdio>
            
            struct typeInner1
            {
                typeInner1(int a = 0) : m_a(a) {} // typeInner1 constructor
                int m_a;
            };
            
            struct typeInner2
            {
                typeInner2(int b = 0) : m_b(b) {} // typeInner2 constructor
                int m_b;
            };
            
            struct typeOuter
            {
                typeOuter(typeInner1& one, typeInner2& two) : m_one(one), m_two(two) {} // typeOuter constructor
            
                typeOuter& set(int a, int b) { m_one.m_a = a; m_two.m_b = b; return *this; }
                typeOuter& print() { printf("typeInner1 a is %i and typeInner2 b is %i\n", m_one.m_a, m_two.m_b); return *this; }
            
                typeInner1& m_one;
                typeInner2& m_two;
            };
            
            typeOuter fun(typeInner1& arg1, typeInner2& arg2)
            {
                return typeOuter(arg1, arg2);
            }
            
            int main()
            {
              typeInner1 arg1;
              typeInner2 arg2;
            
              fun(arg1, arg2).print().set(101, 202).print().set(202, 303).print();
            
              return 0;
            }
            

            输出

            typeInner1 a is 0 and typeInner2 b is 0
            typeInner1 a is 101 and typeInner2 b is 202
            typeInner1 a is 202 and typeInner2 b is 303
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-05-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-03-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多