-1

クラス内に存在する構造をインスタンス化する際に奇妙な問題が発生しています。構造では、デストラクタを (数回) 呼び出し、親オブジェクトのデストラクタを呼び出すことさえあります。

構造を持つクラス:

class Model {

public:
     struct StepModelIO {
         StepModelIO(Model model, ...) {DoConstruction(Model model, ...);}

         StepModelIO(const StepModelIO &other) {DoConstruction(Model model, ...); }

         ~StepModelIO() {}

         DoConstruction() {
             ...
         }
    }
    Model(...) {
       ...
    }

    Model(const Model &other) {DoConstruction(...);}

    ~Model() {
        ...
    }
private:
    DoConstruction(...) {

    }

}

呼び出し機能:

void main() {

    Model::StepModelIO stepArgs = Model::StepModelIO(...);

}

StepModelIO'object' が で、'parent' がである呼び出しの結果のセットModel:

  1. コピー コンストラクターを使用して親を構築する
  2. オブジェクトの構築
  3. 親を破棄
  4. コピー コンストラクターを使用してオブジェクトを構築する
  5. コピー コンストラクターを使用して親を構築する
  6. オブジェクトの構築
  7. 親を破棄
  8. オブジェクトを破壊する
  9. オブジェクトを破壊する (再び...)
  10. 親を破棄

当然のことながら、結果として得られる構造 (a StepModelIO) は、このすべてが発生した後では良好な状態ではなく、パスはばかげているように見えました。親の Model オブジェクトで同じジェネリックを使用するために、このように構造を格納しています。これにより、いくつかの問題が説明される場合があります。

私はコンストラクタとデストラクタで「3 のルール」を使用しようとしましたが (おそらく素朴に)、これをひどく変更した可能性があります。

編集:完全なコード

template<typename U, typename V>
class Model{

public:

    struct StepModelIO {
        Model<U, V> model;
        U u;
        V v;

        StepModelIO() {}

        StepModelIO(Model<U, V> model, U u, V v) {
            this->model = model;
            this->u = u;
            this->v = v;
        }

        StepModelIO (const StepModelIO &other) {
            StepModelIO(other.model, other.u, other.v);
        }

        ~StepModelIO() {
        }
    };

    Model(char * libraryPath) {DoConstruction(libraryPath);}

    Model() {}

    Model (const Model &other) {
        DoConstruction(other.m_LibraryPath);
    }

    ~Model() {
        this->Stop();
    }

    void Init() {
        if (!this->m_Initialised) {
            this->ModelInit();
            m_Initialised = true;
        }
    }

    void Stop() {
        if (this->m_Initialised) {
            this->ModelStop();
            m_Initialised = false;
        }       
    }

    void Restart() {
        this->ModelRestart();
    }

    void Step(U u, V v) {
        ModelStep(u, v);
    }

private:

    char* m_LibraryPath;
    HINSTANCE m_ModelDLL;

    bool m_Initialised;

    typedef int (__cdecl * EmptyModelFunctionPointer)(); // Interpret integer as C code pointer named 'EmptyModelFunctionPointer'
    typedef int (__cdecl * ModelFunctionPointer)(U u, V v);

    EmptyModelFunctionPointer ModelInit;
    EmptyModelFunctionPointer ModelStop;
    EmptyModelFunctionPointer ModelRestart;
    ModelFunctionPointer ModelStep;

    virtual void DoConstruction(char * libraryPath){
        this->m_Initialised = false;
        this->m_LibraryPath = libraryPath;
        this->m_ModelDLL = LoadLibrary(libraryPath);
        this->ModelInit = GetFunction<EmptyModelFunctionPointer>(m_ModelDLL, "Init");   
        this->ModelStop = GetFunction<EmptyModelFunctionPointer>(m_ModelDLL, "Stop");
        this->ModelRestart = GetFunction<EmptyModelFunctionPointer>(m_ModelDLL, "Restart");
        this->ModelStep = GetFunction<ModelFunctionPointer>(m_ModelDLL, "Step");
    }

    template<typename pointerType>
    pointerType GetFunction(HINSTANCE modelLibrary, char * functionName){
        return (pointerType)GetProcAddress(HMODULE (modelLibrary),functionName);
    }
};

発信者:

StepModelIO<Type_1*, Type_2*> stepArgs = StepModelIO<Type_1*, Type_2*>(newModel, &a, &b[0]);
4

2 に答える 2

2

You're passing things by value, which will result in temporary objects being constructed and destructed. Pass them by const reference instead.

change

  StepModelIO(Model model, ...) 

to

  StepModelIO(const Model &model, ...) 

You've now changed the code. So you really want this, I think.

 StepModelIO(const Model<U, V> &model, const U &u, const V &v)
于 2013-10-28T10:01:38.100 に答える