std::vector をコンストラクターのパラメーターとして受け取り、このベクターを使用してバイトを格納する一種のバッファー クラスがあります。このクラスには、バッファから読み書きするためのメソッドがあります。ただし、このバッファー クラスに const std::vector を指定し、書き込み関数がコンパイル時に失敗するか、少なくとも例外をスローする一方で、読み取り関数を引き続き使用できるようにしたいと考えています。
私が思いついた唯一の解決策は、次のようなものでした:
class Buffer
{
public:
Buffer(std::vector<uint8>& vec)
{
this->writeVec = vec
this->readVec = vec;
}
Buffer(std::vector<uint8> const& vec)
{
this->writeVec = null
this->readVec = vec;
}
void write(uint8 i)
{
this->throwIfWriteVecNull();
// do write to writeVec
}
uint8 read()
{
// do read from readVec
}
private:
std::vector<uint8>& writeVec;
std::vector<uint8> const& readVec;
}
個別のライター クラスとリーダー クラス (同様のロジックを 2 つの異なるクラスに分離するのは良くない) を使用せずに、書き込みアクセスのコンパイル時チェックを使用してこれを達成する方法はありますか? const_casts を他の安全でないハックに使用したくありません。また、解決策として別のパターン/アーキテクチャを自由に提案してください。
編集:
回答ありがとうございます。3 つの回答から、user315052 のファサード パターンは、IMO const_cast または複数のポインターがいくつかのクラスを持つよりも悪いため、私が望んでいたものに最も近いものでした。また、もう少し調査を行ったところ、テンプレートを使用して const 型と非 const 型を選択するこのSO q/a に出くわしました。今、私は次のようなものを持っていて、それは完璧に動作します.constバージョンで書き込みを呼び出そうとすると、コンパイル時に「メソッドエラーはありません」. すべてのテンプレートやその他のもののために、コードは少し醜くなりましたが、コンパイル時にエラーが発生することは、例外よりもはるかに優れています。
template <typename BlockType, bool isMutable>
class BaseBuf : boost::noncopyable
{
public:
typedef typename boost::mpl::if_c<isMutable, std::vector<BlockType>, std::vector<BlockType> const>::type VectorType;
BaseBuf(VectorType& blocks) : blocks(blocks)
{
}
void seekReadCursor(size_t pos)
{
// seek to pos
}
bool readBool() const
{
// do read from pos
}
//void read...
//...
protected:
VectorType& blocks;
};
template <typename BlockType>
class ImmuBuf : public BaseBuf<BlockType, false>
{
public:
typedef BaseBuf<BlockType, false> Parent;
typedef typename Parent::VectorType VectorType;
ImmuBuf(VectorType& blocks) : Parent(blocks)
{
}
private:
};
template <typename BlockType>
class MutaBuf : public BaseBuf<BlockType, true>
{
public:
typedef BaseBuf<BlockType, true> Parent;
typedef typename Parent::VectorType VectorType;
MutaBuf(VectorType& blocks) : Parent(blocks)
{
}
// void resize()...
void writeBool(bool b)
{
// do write
}
//void write...
//...
private:
};