5

構造体への参照を含む構造体を持つことは可能ですか? そして、これらはどのように初期化されますか? 以下の短い例を参照してください。

ありがとう

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

6 に答える 6

9

適切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);
}
于 2013-02-09T14:23:49.923 に答える
4

C++11 より前では、 struct のコンストラクターが必要にtypeOuterなり、初期化子リストでメンバー参照を初期化します。

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

C++11 では、イニシャライザ リストを直接 (コンストラクタを自分で定義せずに) 使用するオプションもあります。

typeOuter *ptr = new typeOuter { arg1, arg2 };
于 2013-02-09T14:29:27.387 に答える
3

C++ では、struct. 構造体は基本的にpublic、デフォルトのアクセス修飾子としてのクラスです。

struct Example
{
    // struct fields..

    Example(); // initialize struct objects.
    ~Example(); // perform clean up if necessary.
};
于 2013-02-09T14:24:57.103 に答える
2

あなたの問題は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

一方、参照が a のメンバー変数である場合struct(それらが参照する型に関係なく)、それらはstruct(通常の参照と同様に) が構築されるとすぐにバインドする必要があります。デフォルトで構築してstructから参照をバインドすることはオプションではありません。これは 2 つのステップで行われ、最初のステップの後で参照が初期化されないためです。

したがって、コンストラクターを提供し、そこで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);
}
于 2013-02-09T14:29:18.557 に答える
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));
}
于 2013-02-09T14:40:06.927 に答える
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
于 2013-02-09T14:42:05.223 に答える