我正在尝试用c ++写一个LED条带驱动程序。现在我有一个Strip
类和一个Driver
类; Strip
类抽象出具有多个像素的LED条带,而Driver
类将Strip
类聚合到单个缓冲区中以通过UDP连接发送。
相关的部分类:
class Strip {
public:
...
??? getPixelData();
int getPixelDataLength();
protected:
std::vector<unsigned char> mPixelData;
class Driver {
public:
...
void aggregateStrips();
protected:
vector<unsigned char> mBuffer;
serialize
将所有红绿蓝像素数据写入vector<unsigned char>
。然后,驱动程序调用{{1}}将地址调到Strip.getPixelData()
,然后mPixelData
调出getPixelDataLength()
的字节数。
memcpy()
做了类似的事情:
aggregateStrips()
我的问题是 - int packetLength = 0;
for(auto strip : Strips) {
memcpy(&mBuffer[packetLength], strip->getPixelData(), strip->getPixelDataLength());
packetLength += strip.getPixelDataLength();
}
应该返回什么?它应该向向量返回一个智能指针(getPixelData()
?)吗?或者也许是参考?我只想要地址(和长度),因为我打算shared_ptr
它。
谢谢!
答案 0 :(得分:7)
通常,您会返回对向量(std::vector<unsigned char> const &
)的const引用,在这种情况下,您还应该使方法成为const,因为它不会修改对象:
std::vector<unsigned char> const & getPixelData() const;
来电者可以决定是否需要复制。
// Causes copy-initialization.
std::vector<unsigned char> copy = a_strip.getPixelData();
// Binds a new reference to the existing vector; no copy is made.
std::vector<unsigned char> const & not_a_copy = a_strip.getPixelData();
getPixelDataLength()
也可能成为该类的const成员。尝试使任何不改变对象const成员的成员,因为它允许在const Strip
对象上调用它们。
答案 1 :(得分:1)
std::vector
通过其data()
方法公开其管理的缓冲区,在这种情况下,该方法将返回unsigned char*
或const unsigned char *
,具体取决于Strip
/ mBuffer
是const
。这个方法是在C ++ 11中添加的。
作为旁注,将您的只读方法设置为const
(在带括号的方法参数之后)是一个很好的设计,因此可以在类const
实例上调用它们并且不允许修改任何成员变量。
我将getPixelData()
定义为:
const unsigned char* getPixelData() const
{
return mBuffer.data();
}
同样,我将getPixelDataLength()
写为:
std::size_t getPixelDataLength() const
{
return mBuffer.size();
}
另一方面,for(auto strip : Strips)
实际上复制了每个条带。如果您引用每个现有条带而不复制它,您的程序将更有效:
for (const auto& strip : Strips) {
// ...
}
答案 2 :(得分:1)
我不会返回向量,而是将一对(const)迭代器返回到向量的开头和结尾:
using PixelIterator = std::vector<unsigned char>::const_iterator;
class Strip {
...
PixelIterator begin() const {
return mPixelData.begin();
}
PixelIterator end() const {
return mPixelData.end();
}
};
如果可以,我会避免在c ++中使用memcopy
。使用迭代器,您可以轻松附加到缓冲区向量:
for(const auto& strip : strips)
mBuffer.insert(mBuffer.end(). strip.begin(), strip.end());
正如已经指出的那样,在基于范围的循环中使用auto&
以避免复制。
您不需要维护单独的长度变量,因为您可以轻松获得std::vector
的大小。