返回对大小不变的指针数组的引用的最佳方式是什么
What is the best way to return reference to a constant sized array of pointers?
我有一个指针数组,声明为类成员,如下所示:
class Bar
{
private:
static constexpr int SIZE = 10;
Foo* m[SIZE];
}
在我的一个类方法中,我想返回一个指向这个数组的指针(或者最好是一个引用)。数组在编译时有一个已知的大小,但我会记录我在其中放入了多少项(它是一个缓冲区)。
在C++11中,返回对此数组的引用的最佳方式是什么?
以下是我尝试过的东西:
GetArray(Foo* &f[], unsigned &size) const
我喜欢这种语法,因为它清楚地表明引用值是指针数组,但这会导致编译器错误:Declared as array of references of type Foo*
GetArray(Foo** &f, unsigned &size) const
{
f = m;
size = mSize;
}
给我:错误:分配给Foo **' from incompatible type Foo *const[10]
。将mFoo
转换为(Foo**)
可以减轻错误,但IMHO,这并不优雅。
还没有人使用std::array
发布答案,这是一个非常简单的替代:
class Bar
{
std::array<Foo *, 10> m;
public:
std::array<Foo *, 10> & getArray() { return m; }
std::array<Foo *, 10> const & getArray() const { return m; }
};
在我看来,这比使用C风格数组版本所需的困难要简单得多。
为了避免代码重复,您可以typedef std::array<Foo *, 10> FooArray;
。
同时具有const
和非const
实现的技术是返回引用或指针的访问器函数的常见模式。(当然,如果您的访问器按值返回,则这不是必需的)。
在大多数情况下,我会寻求使用std::array
或std::vector
。如果你决定使用一个原始数组,那么你可以这样做:
typedef int Foo;
typedef Foo* (&FooPtrArrayRef)[10]; // to make the syntax less hairy
class Bar
{
private:
Foo* m[10];
public:
// First way without using typedef
Foo* (&getArray())[10]
{
return m;
}
// Nicer looking way with a typedef
FooPtrArrayRef getArrayByRef()
{
return m;
}
};
int main()
{
Bar b;
Foo* (&array)[10] = b.getArray();
std::cout << (sizeof(array) / sizeof(Foo*)) << 'n';
// Alternative using "size deduction"
Foo* (&array2)[sizeof(b.getArray()) / sizeof(Foo*)] = b.getArray();
std::cout << (sizeof(array2) / sizeof(Foo*)) << 'n';
// MUCH nicer using the typedef
FooPtrArrayRef array3 = b.getArrayByRef();
std::cout << (sizeof(array3) / sizeof(Foo*)) << 'n';
}
不过,语法相当晦涩。
这种方法的好处是,它保留了通过引用传递的数组的完整类型信息。模糊语法对于避免类型塌陷为Foo**
是必要的。通过保留数组的完整类型,您可以在编译时使用sizeof()
运算符来了解其大小。
这里有另一种方法,它将数组引用和当前大小作为元组返回:
#include <tuple>
#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
struct Foo {};
using FooBuffer = Foo*[10];
class Bar
{
public:
Bar()
: _m { nullptr }
{
_m[0] = new Foo;
_m[1] = new Foo;
_items = 2;
}
~Bar() {
for(auto fp : _m)
delete fp;
}
std::tuple<FooBuffer&, size_t> getInfo() {
return std::make_tuple(std::ref(_m), _items);
}
private:
Foo* _m[10];
size_t _items;
};
int main() {
Bar b;
auto info = b.getInfo();
FooBuffer& buf = std::get<0>(info);
size_t items = std::get<1>(info);
for(Foo** p = buf ; p != buf + items ; ++p) {
std::cout << "Foo at " << std::hex << *p << std::endl;
}
return 0;
}
相关文章:
- 关于引用数组位置的问题
- 使用指针交换而不引用数组C++
- 对于Boost.Propertytree,有没有办法使用JSON点表示法来引用数组元素?
- 如何在递归函数中调用引用数组?
- 动态指针引用数组由三元运算符返回值,但有异常
- 为什么没有 std::string 构造函数来引用数组
- 指针/引用数组
- 错误 C2234:引用数组是非法的
- 引用数组的方法
- 通过引用数组值进行交换
- 引用数组涉及的技术问题
- 引用数组的函数调用
- 从其他类中的类引用数组
- 如何使用变量名称引用数组位置
- 在 OpenGL 中呈现三角形结构引用数组
- 如何取消引用数组元素(C++)
- c++引用数组数组(指针到指针?)
- 指向指针的指针如何能够引用数组
- C++取消引用数组
- c++中引用数组中对象的共享指针