我有一种缓冲区类,它将 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;
}
有没有办法在没有单独的编写器和读取器类的情况下实现这一点(它将相似的逻辑分离到两个不好的不同类)并且编译时检查写访问?我不想将 const_casts 用于任何其他不安全的黑客攻击。也可以随意建议替代模式/架构作为解决方案。
编辑:
谢谢大家的回答。从三个答案中,user315052 的外观模式最接近我想要的东西,因为 IMO const_cast 或多个指针比只有几个类更糟糕。我还做了更多的研究,偶然发现了这个SO q/a,其中模板用于在 const 和非 const 类型之间进行选择。现在我有类似以下的东西并且它工作得很好,如果我尝试在 const 版本上调用 write,我会在编译时得到“无方法错误”。由于所有模板和东西,代码有点难看,但在编译时出错比异常要好得多。
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:
};