11

いくつかのポインターを含む構造体があります。これらの値を変更できないようにしたい。ただし、単に const を前に書いても、構造体のメンバーは変更不可にはなりません。

typedef struct{
  int *x;
  int *y;
}point;

void get(const  point *p,int x, int y){
  p->x[0]=x;//<- this should not be allowed
  p->y[0]=y;//<- this should not be allowed
}

誰かが私を正しい方向に向けることができますか?

編集:

したがって、関数プロトタイプを使用して、構造体に属するすべてのものを変更できないようにする簡単な方法はないように思われます。

4

4 に答える 4

9

const ポイント型とミュータブル ポイント型を定義することで、型キャストせずにそれを行うことができます。

typedef struct{
    const int *  x;
    const int *  y;
} const_point;

typedef struct{
    int *  x;
    int *  y;
} mutable_point;

typedef union __attribute__((__transparent_union__)) {
    const_point cpoint;
    mutable_point point;
} point;

次に、point または const_point 型 (mutable_point 型ではありません) を使用して関数パラメーターを宣言します。

ポイント型オブジェクトは const_point 型に透過的にキャストされますが、その逆はできません。これにより、型の安全性を高めることができます。

gcc の例については、http: //toves.freeshell.org/xueg/を参照してください。

トランスペアレント ユニオンは、私がチェックした C++ の最後のバージョンではサポートされていないことに注意してください (最新の C++ 標準についてはわかりません)。そのため、移植性の問題が予想されます。

また、特に複雑な構造体がある場合は、コードの読み取りと保守が難しくなる可能性があります。例: x または y のいずれかが const であるポイント型を持つことができます。または、constness に応じて複数の型に対して複数の構造体を定義する必要があるかもしれない四角形などの別の構造体にポイント構造体を埋め込む必要がある場合があります。

全体として、余分な手間をかける価値があるかどうかはわかりません。

于 2013-10-17T23:55:40.420 に答える
4

私があなたの質問を正しく理解していれば、構造体オブジェクト全体の constness をその構造体メンバーが指すオブジェクトに自動的に伝播させたいと考えています。つまり、構造体オブジェクトが const でない場合、配列は変更可能であるべきですが、構造体オブジェクトが const である場合、配列は変更可能であってはなりません。

もしそうなら、残念ながらC言語では実現できません。

C++ では、(データ メンバーに直接アクセスするのではなく) アクセサー メンバー関数を使用してデータ メンバーにアクセスすることをユーザーに強制することで、これを行うことができます。しかし、C では単純に実行できません。

于 2012-11-01T17:09:21.550 に答える
2

書くときに何を確立する必要があるかを説明するには

point str;

point *p=&str;

ここで、 p はポイント型のstr へのポインタです

const として宣言すると、p が定数ポインターであることを意味します。これは、構造体に含まれる可能性のあるポインターを制限しません。

ネスを構造内に適用する場合constは、構造内のポインターも const として定義する必要があります。

typedef struct{
   const int *  x;
   const int *  y;
}point;

再び私の要点をプッシュするために、パラメーターを次のように宣言します

    void get(point * const  p,int x, int y) 
   //Constant Pointer ( *to prevent p from pointing to anything else*)

    //    AND

   //Make the pointers inside point structure constant
   //( *to prevent the int pointers x & y from pointing to anything else*)

それが指している構造体も const の場合

      void get(const point * const p, int x, int y)
     //Constant Pointer to constant structure 
于 2012-11-01T16:45:12.303 に答える
1

これは、。以外のポインタが指すメモリコンテンツを変更するためですp

pへの2つのポインタを含む構造体上のポイントintp指しているメモリを変更するのではなく、別のメモリ領域を変更します。したがって、コンパイラはそれで問題ありません。

       +----------+
p ->   |    x     |  -> wherever  
       +----------+
       |    y     |  -> another place in memory
       +----------+

nessodは継承できませんconstpもしあなたが書いていたら p->a = array;、コンパイラは文句を言ったでしょう。これconstは、そのポインタを介してメモリを変更しないという契約にすぎません。

于 2012-11-01T16:41:12.490 に答える