3

この質問の短いバージョン: クラスの最初のデータ メンバーへのポインターは、そのすべてのデータ メンバーへのポインターになりますか?

討論:

私はいくつかのサンプル コードを読んでいますが、これは興味深いものです。特定の関数 (この場合はglUniformMatrix4fvOpenGL の C 関数) がパラメーターとして配列を受け取る場合、次のように、配列の最初の要素のアドレスへのポインターを使用する一般的な C の方法で渡されます。

glUniformMatrix4fv(glvariable, 1, 0, &newmatrix[0]); // newmatrix を参照

この開発者は、合計 16 個の float の 4X4 マトリックスを作成するための C++ クラスを持っています。ただし、そのクラスのデータ メンバーは、それぞれ 4 つのデータ メンバーの 4 つの個別のベクトルに分割されます。

クラスのデータメンバーは次のとおりです。

vec4 x;
vec4 y;
vec4 z;
vec4 w;

このvec4クラスは、次のデータ メンバーを提供します。

T x;
T y;
T z;
T w;

vec4 x次に、最初のデータ メンバーだけを指す関数を作成します。

    const T* Pointer() const
{
    return &x.x;
}

vec4そしてどういうわけか、これは奇跡的に 4 つのオブジェクトすべてとそれぞれの 4 つのコンポーネントを送信することに変換されます。

glUniformMatrix4fv(modelviewUniform, 1, 0, modelviewMatrix.Pointer());

私は C++ にかなり慣れていませんが、データ メンバーを 1 つだけ指定して、残りのすべてのメンバーも同様に送信されることを期待できることに驚きました。クラスが特定の順序でそれらを定義しているためですか?クラス定義で別の順序で定義されていたらどうなるでしょうか?

4

1 に答える 1

8

これはC++オブジェクトモデルです。同じアクセスレベル(private/ public/ protected)内で、オブジェクトプロパティが順番に(C ++ 11)、アクセス指定子のないメンバー(C ++ 03)でも同じであることが保証されます。

これはあなたがしていることが良い考えであるという意味ではありません。キャストを避けて、関数にもう少し作業を行わせることをお勧めします。

C ++ 11:

9.2クラスメンバー[class.mem]

14)同じアクセス制御(条項11)を持つ(非ユニオン)クラスの非静的データメンバーは、後のメンバーがクラスオブジェクト内でより高いアドレスを持つように割り当てられます。アクセス制御が異なる非静的データメンバーの割り当て順序は指定されていません(11)。実装の調整要件により、2つの隣接するメンバーがすぐに割り当てられない場合があります。仮想関数(10.3)と仮想基本クラス(10.1)を管理するためのスペースの要件も同様です。

C ++ 03

9.2クラスメンバー[class.mem]

12)アクセス指定子が介在せずに宣言された(非ユニオン)クラスの非静的データメンバーは、後のメンバーがクラスオブジェクト内でより高いアドレスを持つように割り当てられます。アクセス指定子で区切られた非静的データメンバーの割り当て順序は指定されていません(11.1)。実装の調整要件により、2つの隣接するメンバーがすぐに割り当てられない場合があります。仮想関数(10.3)と仮想基本クラス(10.1)を管理するためのスペースの要件も同様です。

于 2013-01-16T06:18:44.280 に答える