0

私は世論調査用のプログラムを書いており、クラス「Partito」を使用しています。

#pragma once

ref class Partito
{
protected:
    //System::String ^nome;
    int IndexP;             //Index Partito
    float MaxConsenso;
    float consensoTot;
    int consenso;
//workaround according to Hans Passant:
//  char Risposta[5];           
    array<int> ^Risposte;// Risposte means anwers.
//workaround end
System::Drawing::Color colore;

public:
    Partito(
        int _IndexP,
      float _consensoTot, int consenso

        array<int> ^_Risposte      // workaround

);      //costruttore

    void CalcCons(int consenso);

    float GetConsensoTot(void);
};
    };

定義は次のとおりです。

#include "StdAfx.h"
#include "Partito.h"

//Partito::Partito(void)
Partito::Partito(
              int _IndexP,
            float _consensoTot,
            int consenso
//workaround start
            array<int> ^_Risposte //workaround
//workaround end
)
{
        //char Risposta[5]; 
//workaround start
     Risposte=gcnew array<int>(5); //workaround
    Risposte=_Risposte; //workaround
//workaround end.
    IndexP =_IndexP;
    consensoTot = _consensoTot;
    MaxConsenso = 12;
}
void Partito::CalcCons(int consenso)
{

consensoTot+=(consenso*100)/MaxConsenso;
}

float Partito::GetConsensoTot(void)
{
    return consensoTot;
}

現在、回避策により、コンパイラは問題なくそれを受け入れます。ファイル「Form1h」で、問題なく配列を初期化できるようになりました。

Form1(void)
{
            InitializeComponent();
            //
            //TODO: aggiungere qui il codice del costruttore.
            //

このように配列を初期化して、オブジェクトを定義します。

Partito^ ExampleParty = gcnew Partito(0,0,0,gcnew array<int>{0,1,2,2,0});
.
.
.
}
4

2 に答える 2

2

このコードは、簡単な例に要約できます。

ref class foo {
public:
    int array[6];   // C4368: mixed types are not supported
};

ここで何が起こっているかというと、C++/CLI コンパイラーが足を引っ張るのを防いでいるのです。次のようなショットです。

foo^ obj = gcnew foo;
NativeFunction(obj->array, 6);

NatievFunction() は引数として int* を取ります。NativeFunction() が実行されているときにガベージ コレクターが起動すると、これは致命的です。ヒープを圧縮するときに、メモリ内の foo オブジェクトを移動します。int* を無効にします。ネイティブ関数がガベージを読み取ったり、配列への書き込み時に GC ヒープを破壊したりすると、災害が発生します。

回避策は、int[] の代わりに int* を使用して、配列のメモリがnew演算子を使用してネイティブ ヒープから割り当てられ、常に安定するようにすることです。コンストラクタで割り当てます。再度解放するには、デストラクタとファイナライザが必要です。または、管理された配列 (array<int>^この場合は ) を使用するだけです。ネイティブ関数に渡す必要がある場合は、 pin_ptr<> を使用して一時的に固定できます。

于 2013-09-19T19:32:25.103 に答える