0

以下の例に示すように、2 つのクラスと追加の機能コードの間に関係があります。このクラスは、クラス インスタンスMiddleManへのポインターのコンテナーをいくつか保持します。DataObjectあるコンテナーのデータ オブジェクトへの読み取り専用アクセスを強制し、他のコンテナーのデータ コンテナーへの書き込みアクセスを許可したいと考えています。のユーザーは、コンテナー自体 (メンバー)MiddleManを直接変更することはできません。ptr_vector

constメンバー関数DataObjectを介してアクセスすると、ポインターにconstプロモーションが発生していると思います。MiddleManどうすればこれを回避できますか? 私のオブジェクト関係では、インスタンスMiddleManを論理的に所有していません。したがって、インスタンスを const で保護DataObjectしたくありません。DataObject

boost::ptr_vectorSTLコンテナはこの種のことでより問題になる可能性があることを理解しているので、コンテナを使用しました。しかし、私の問題は解決しませんでした。で const_cast を使用できてうれしいですがMiddleMan、方法がわかりません。

// const correctness access through middleman example
// g++ -I/Developer/boost  ptr_container_ex.cc
#include <boost/ptr_container/ptr_vector.hpp>

struct DataObject
{
    DataObject(size_t n) : _data(new float[n]) {}
    ~DataObject() {delete _data;}
    float * dataNonConst() { return _data; }
    const float * dataConst() const { return _data; }
    float * _data;
};


struct MiddleMan
{

    typedef boost::ptr_vector<DataObject> containerVec_t;

    const containerVec_t & inputVars() const { return _inputVars; }
    const containerVec_t & outputVars() const { return _outputVars; }

    void addInputVar(  DataObject * in  ) { _inputVars.push_back( in ); }
    void addOutputVar( DataObject * out ) { _outputVars.push_back( out ); }

    containerVec_t _inputVars, _outputVars;

};

// just an example that the DataObject instances are managed externally
DataObject g_dataInstances[] = {DataObject(1), DataObject(2), DataObject(3)};

MiddleMan theMiddleMan;


int main()
{
    theMiddleMan.addInputVar( &g_dataInstances[0]);  // this is just setup
    theMiddleMan.addOutputVar( &g_dataInstances[1]);

    const MiddleMan & mmRef = theMiddleMan; // I actually only have a const ref to work with

    // read data example
    const MiddleMan::containerVec_t & inputs = mmRef.inputVars();
    float read = inputs[0].dataConst()[0];

    // write data example
    const MiddleMan::containerVec_t & outputs = mmRef.outputVars();
    float * data_ptr = outputs[0].dataNonConst(); // COMPILER ERROR HERE:

    return 0;
}

コンパイラ出力を取得しています:

ptr_container_ex.cc: In function ‘int main()’:
ptr_container_ex.cc:49: error: passing ‘const DataContainer’ as ‘this’ argument of ‘float* DataContainer::dataNonConst()’ discards qualifiers
4

2 に答える 2

1

const アクセスを行わないすべての場所で、const 修飾子を除外する必要があります。

containerVec_t & outputVars() { return _outputVars; } //Change definition in MiddleMan class

MiddleMan::containerVec_t & outputs = theMiddleMan.outputVars(); //Change reference type
float * data_ptr = outputs[0].dataNonConst(); //No compiler error here
于 2013-01-10T05:17:45.730 に答える
-1

1 つの作業シナリオではconst_cast、outputVars へのアクセスに使用されます。コンテナ全体への参照を返すことはできませんが、開始イテレータと終了イテレータを返すために必要な機能を取得できます。

// const correctness access through middleman example
// g++ -I/Developer/boost  ptr_container_ex.cc
#include <boost/ptr_container/ptr_vector.hpp>

struct DataObject
{
    DataObject(size_t n) : _data(new float[n]) {}
    ~DataObject() {delete _data;}
    float * dataNonConst() { return _data; }
    const float * dataConst() const { return _data; }
    float * _data;
};


struct MiddleMan
{
    typedef boost::ptr_vector<DataObject> containerVec_t;

    containerVec_t::iterator outputVarsBegin() const { return const_cast<containerVec_t&>(_outputVars).begin(); }
    containerVec_t::iterator outputVarsEnd() const { return const_cast<containerVec_t&>(_outputVars).end(); }

    const containerVec_t & inputVars() const { return _inputVars; }

    void addInputVar(  DataObject * in  ) { _inputVars.push_back( in ); }
    void addOutputVar( DataObject * out ) { _outputVars.push_back( out ); }

    containerVec_t _inputVars, _outputVars;

};

// just an example that the DataObject instances are managed externally
DataObject g_dataInstances[] = {DataObject(1), DataObject(2), DataObject(3)};

MiddleMan theMiddleMan;


int main()
{
    theMiddleMan.addInputVar( &g_dataInstances[0]);  // this is just setup
    theMiddleMan.addOutputVar( &g_dataInstances[1]);

    const MiddleMan & mmRef = theMiddleMan; // I actually only have a const ref to work with

    // read data example
    const MiddleMan::containerVec_t & inputs = mmRef.inputVars();
    float read = inputs[0].dataConst()[0];

    // write data example
    float * data_ptr2 = mmRef.outputVarsBegin()->dataNonConst(); // WORKS

    return 0;
}
于 2013-01-10T22:33:58.227 に答える