定义一个生成元素向量的函数时,正确的方法是什么?
What is the correct approach while defining a function that generates a vector of elements C++
我必须在c++中定义一个函数来生成类Foo的向量并返回它。
我可以用不同的方式来定义它,它们都是等价的:
C风格参数传递:
void generateFooVector(vector<Foo> * result)
{
for (int i = 0; i < 100; i++)
{
Foo f = Foo();
result->push_back(f);
}
}
int main()
{
vector<Foo> result;
generateFooVector(&result);
}
引用传递:
void generateFooVector(vector<Foo> & result)
{
for (int i = 0; i < 100; i++)
{
Foo f = Foo();
result->push_back(f);
}
}
int main()
{
vector<Foo> result;
generateFooVector(result);
}
实例化vector并返回指针:
vector<Foo> * generateFooVector()
{
vector<Foo> * result = new vector<Foo>();
for (int i = 0; i < 100; i++)
{
Foo f = Foo();
result->push_back(f);
}
return result;
}
int main()
{
vector<Foo> * result = generateFooVector();
}
C风格传递和实例化Foo类:
void generateFooVector(vector<Foo *> * result)
{
for (int i = 0; i < 100; i++)
{
Foo * f = new Foo();
result->push_back(f);
}
}
int main()
{
vector<Foo *> result;
generateFooVector(&result);
}
引用传递+ Foo实例:
void generateFooVector(vector<Foo *> & result)
{
for (int i = 0; i < 100; i++)
{
Foo * f = new Foo();
result->push_back(f);
}
}
int main()
{
vector<Foo *> result;
generateFooVector(result);
}
Vector实例+ Foo实例:
vector<Foo*> * generateFooVector()
{
vector<Foo*> * result = new vector<Foo*>();
for (int i = 0; i < 100; i++)
{
Foo * f = new Foo();
result->push_back(f);
}
return result;
}
int main()
{
vector<Foo *> * result = generateFooVector();
}
按值传递:
vector<Foo> generateFooVector()
{
vector<Foo> result;
for (int i = 0; i < 100; i++)
{
Foo f = Foo();
result->push_back(f);
}
return result;
}
int main()
{
vector<Foo > result = generateFooVector();
}
也许还有很多其他的解决方案。
当前所有的方法对于如何在作用域内分配内存都有不同的含义。
也许我缺乏理论,但我真的很困惑,我如何才能决定哪个是每个用例的更好的替代方案,为什么一个比另一个更好。你能帮我吗?
只管做
vector<Foo> generateFooVector()
{
return vector<Foo>(100);
}
它叫做modern c++
该函数已在标准库中定义,称为std::vector<Foo>
的构造函数。你可以把它命名为(c++ 11风格)
auto v = std::vector<Foo>(n); // create n default constructed Foo() objects
或c++ 98风格的
(在c++ 11中也有效)std::vector<Foo> v(n);
我不会尝试包装这个
- 首先,你不想在
- 中隐藏像100这样的幻数,而不是在参数列表(模板或运行时)中。 不包装构造函数的另一个原因是为了避免读者产生混淆。如果我遇到一个
generateVector
函数,第一个问题是:"与普通构造函数调用相比,这个函数是否做了其他/额外的事情?"我确实看到了两个主要不同的实现- vector<Foo*>
和vector<Foo>
。其他都是参数传递的变体。
如你所知,vector在添加时复制元素,在删除vector时调用元素析构函数。所以在vector<Foo*>
的情况下,你避免了对象的复制,如果对象非常大的话。但是你负责删除内存。所以最好存储带有自动删除功能的智能指针,比如vector<shared_ptr<Foo>>
或vector<unique_ptr<Foo>>
(这里需要移动逻辑)。指针的类型取决于应用程序的逻辑。
顺便说一句,
Foo* pFoo = new Foo; // also default constructor call
(你知道与new Foo()
的区别吗?)
vector<Foo> v(n); // init vector with n Foo objects calling default ctor
我可能会采用上面的引用传递方法。
通常在C和c++中,您不希望返回需要稍后重新分配的对象,因为这会导致泄漏。
我认为这很大程度上取决于实际使用情况——最关键的是foo有多重?如果foo是一个轻量级对象并且是类似pod的类型,那么我将使用
Vector<Foo> generateFoo();
或者像
Vector<Foo*> generateFoo();
可能更有用。
标准类型是有效的,大多数喜欢被复制,所以它们对向量*解决方案没有什么优势。一般来说,返回(或使用)一个需要稍后删除的原始指针可能是不明智的——在这种体系结构中很容易产生泄漏。所以,不妨看看foo对象的各种智能指针选项。
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 这里的字符串函数是什么意思
- 这个函数是什么意思(我的英语sry)
- C++ 中的 use 函数是什么?
- C++中的编译时函数是什么?
- 使用 DnsQuery 或 getaddrinfo 的正确函数是什么?
- Lua 中看起来像表的函数是什么?
- "AfxIsValidAddress"函数的等效标准函数是什么?
- 子类的构造函数后跟冒号后的基类构造函数是什么意思?
- MFC 用于计算控件的高光、阴影等的算法或函数是什么?
- 具有多个非可选参数的转换构造函数是什么样子的?为什么它有意义
- 不确定 c++ 中的常量函数是什么
- 指针的最快散列函数是什么
- 注册用于提升io_service的每个对象的回调函数是什么?
- 在 g++ 中生成 "-L" 和 -rpath 标志的等效函数是什么
- Boost.Python中的dispatch函数和forwarding函数是什么意思
- 给定情况下的良好哈希函数是什么
- C++ 中的"导出函数"是什么意思?
- C++ std::unordered_map 中使用的默认哈希函数是什么