偏移和传递矢量参考

发布于 2024-11-04 08:09:32 字数 899 浏览 0 评论 0原文

使用数组时,您可以执行类似的操作,

class SomeClass
{
public:
    int* LockMember( size_t& numInts );

private:
    int*   member;
    size_t numInts;
};

int* SomeClass::LockMember( size_t& out_numInts )
{
    out_numInts = numInts - 1;
    return member + 1;
}

以返回一定量的数组偏移量,以防止某人修改连续内存的某些部分,或者至少表明对象的这部分连续内存应保持不变。

由于我到处都使用向量,我想知道是否有某种方法可以完成同样的事情:

class SomeClass
{
public:
    std::vector<int> LockMember( void );

private:
    std::vector<int> member;
};

std::vector<int> SomeClass::LockMember( void )
{
   // somehow make a vector with its beginning iterator pointing to member.begin() + 1
   // have a size smaller by one, still the same end iterator. The vector must be 
   // pointing to the same data as in this class as it needs to be modifiable.

   return magicOffsetVector;
}

用真实代码替换注释部分。有什么想法吗?

When using arrays you can do something like

class SomeClass
{
public:
    int* LockMember( size_t& numInts );

private:
    int*   member;
    size_t numInts;
};

int* SomeClass::LockMember( size_t& out_numInts )
{
    out_numInts = numInts - 1;
    return member + 1;
}

To return an array offset by some amount so as to prevent someone from modifying some part of contingeous memory, or, atleast, show some intent that this part of contingeous memory of the object should remain untouched.

Since I use vectors everywhere, I am wondering if there was some way to accomplish the same sort of thing:

class SomeClass
{
public:
    std::vector<int> LockMember( void );

private:
    std::vector<int> member;
};

std::vector<int> SomeClass::LockMember( void )
{
   // somehow make a vector with its beginning iterator pointing to member.begin() + 1
   // have a size smaller by one, still the same end iterator. The vector must be 
   // pointing to the same data as in this class as it needs to be modifiable.

   return magicOffsetVector;
}

With the commented part replaced by real code. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱格式化 2024-11-11 08:09:32

如果我理解正确的话:您想要一些由两部分组成的内存:一开始您想要一些无法触及的东西,之后您想要一些可供客户端代码打开使用的东西。

您可以按照以下代码执行某些操作。这将为客户端代码提供一份可供使用的副本。但这确实意味着您必须进行大量复制。

class SomeClass
{
public:
    std::vector<int> getMember( void ) const;
    void setMember(std::vector<int> newContent);

private:
    std::vector<int> member;
    size_t magicOffset;
};

// Read restricted part
std::vector<int> SomeClass::getMember( void ) const
{
    return vector<int>(member.begin() + magicOffset, member.end());
}

// Assign to restricted part
void SomeClass::setMember(const std::vector<int>& v)
{
    std::copy(v.begin(), v.end(), member.begin() + magicOffset);
}

为了避免复制,您可以为两个向量分配内存,一个用于受保护的部分,一个用于不受保护的部分,并使用placement new将两个向量放入该内存中,从而确保它们是连续的记忆。然后让客户端代码或多或少自由地访问向量的公共部分。然而,向量中仍然存在簿记变量的问题,基本上这将是一个等待爆炸的可怕黑客。

但是,如果您只需要基于每个元素访问不受限制的部分,则可以只对参数进行范围检查,即:

int getElement(size_t idx)
{
    idx += magicOffset;
    if (idx > member.size() || idx < 0) throw std::out_of_range("Illegal index");

    return member[idx];
}

然后提供 setElement 或返回 int&.

If I understand you correctly: You want some memory with two parts: At the beginning you want something that can't be touched, and after that you want something that is open for use by client code.

You could do something along the following code. This will give the client code a copy to play with. This does mean you would have to do a lot of copying, though.

class SomeClass
{
public:
    std::vector<int> getMember( void ) const;
    void setMember(std::vector<int> newContent);

private:
    std::vector<int> member;
    size_t magicOffset;
};

// Read restricted part
std::vector<int> SomeClass::getMember( void ) const
{
    return vector<int>(member.begin() + magicOffset, member.end());
}

// Assign to restricted part
void SomeClass::setMember(const std::vector<int>& v)
{
    std::copy(v.begin(), v.end(), member.begin() + magicOffset);
}

In order to avoid the copying, it is possible that you could allocate memory for two vectors, one for the protected part and one for the unprotected part, and use placement new to put both vectors into that memory, thus ensuring that they are in contiguous memory. And then give the client code more or less free access to the public part of the vector. However, there's still the thing with bookkeeping variables in vector, and basically this would be an awful hack that's just waiting to blow up.

However, if you only need access to the unrestricted part on a per-element basis, you could just do range-checking on the arguments, i.e.:

int getElement(size_t idx)
{
    idx += magicOffset;
    if (idx > member.size() || idx < 0) throw std::out_of_range("Illegal index");

    return member[idx];
}

And then either provide a setElement, or return int&.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文