2

来自 Java 背景,我试图理解 C++ 中的指针/引用。我正在尝试从函数返回一个向量。写作:

vector<char*> f(){
    vector<char*> vec;
    return vec;
}

会返回向量的副本,对吗?更好的方法是返回指向向量的指针,如下所示:

vector<char*>* f(){
    vector<char*>* vec = new vector<char*>;
    return vec;
}

我是正确的,还是完全错误的?

4

3 回答 3

1

在 C++03 中,按值返回最有可能导致 RVO(返回值优化),这将省略不必要的副本。在 C++11 中,移动语义将负责复制。

那么,为什么首先按值返回?因为它可以防止具有动态生命周期的不必要的对象。您的示例代码也不尊重您的函数用户可能想要使用的任何分配策略。

一般来说,即使在 C++11 中,返回一个容器仍然是一个坏主意:它将用户限制在该特定容器中,因为不可能跨容器移动,只能复制。标准库用OutputIteratorS. 您的算法很可能会写成:

template<typename OutputIterator>
OutputIterator f(OutputIterator o);

这样你就可以从容器中抽象出来,也可以规避最初的问题。

于 2013-02-15T01:17:09.937 回答
0

你错了,你不想在 C++ 中这样做。几乎每个 C++ 编译器都有所谓的命名返回值优化,这将(有效地)vec通过为堆栈上的返回值分配空间来移动而不是复制,然后基本上“就地”构造。这消除了开销。

维基百科关于此的文章给出了合理的概述。

于 2013-02-15T01:04:15.360 回答
0

我是正确的,还是完全错误的?

这是完全错误的,至少在存在移动语义的 C++11 中,只要您不需要创建返回值的别名(这似乎不是您的情况,即使是这样,也会可能需要使用智能指针而不是原始指针)。

现在可以按值返回向量了。大多数时候,即使在 C++98 中,编译器也会忽略对复制构造函数的调用(以及 C++11 中的移动构造函数)。这称为(命名的)返回值优化

在 C++11 中,标准库的所有容器都支持移动构造函数,因此即使没有省略复制或移动,按值返回容器也不昂贵。

于 2013-02-15T01:04:24.940 回答