初始化包含对其他结构体引用的结构体

7

能否创建一个包含对其他结构体的引用的结构体?如果可以,如何初始化这些引用?请参考下面的简短示例。

谢谢

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);
}

1
顺便提一下,在C++中,typedef struct {...} foo;不是“惯用语”,直接写struct foo {...};更常见(并且可以让你直接使用foo作为类型名称)。 - Mat
6个回答

10
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);
}

5

C++11之前,您需要为结构体 typeOuter 编写构造函数,并在初始化列表中初始化成员引用:

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

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

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

3
在C++中,您可以为自己的struct创建构造函数。 结构体基本上是具有默认访问修饰符public的类。
struct Example
{
    // struct fields..

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

3

您的问题不在于有对struct的引用,而是在于一般情况下初始化引用。无论是对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 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);
}

1

你可以添加一个构造函数,但也可以使用聚合初始化和工厂函数。这适用于所有版本的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));
}

0

嗯..

#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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接