15

在 C++ 中,我的方法应该返回对象还是指向对象的指针?如何决定?如果是运营商呢?我该如何定义?

还有一件事 - 如果指针变成一个向量,我如何在返回后找出它的大小?如果不可能,正如我认为的那样,我应该如何在没有这个限制的情况下正确返回一个数组?

4

3 回答 3

10

在 C++ 中,我的方法应该返回对象还是指向对象的指针?如何决定?

从 C++11 开始,我们在 C++ 中有了移动语义,这意味着它像以前一样简单,现在也可以快速按值返回。这应该是默认值。

如果是运营商呢?我该如何定义?

许多运算符,例如operator=通常返回*this

X& X::operator=(X rhs); 

如果您想遵守通常的模式(并且应该),您需要为每个操作员查找它。从这里开始:运算符重载

正如 Ed S 所指出的,返回值优化也适用(甚至在 C++11 之前),这意味着您返回的对象通常不需要被复制或移动。

所以,这是现在返回东西的方式:

std::string getstring(){ 
   std::string foo("hello");
   foo+=" world";
   return foo;
}

我在这里创建了一个 foo 对象的事实不是我的意思,即使你只是这样做return "hello world";也是要走的路。

还有一件事 - 如果指针变成一个向量,我如何在返回后找出它的大小?如果不可能,正如我认为的那样,我应该如何在没有这个限制的情况下正确返回一个数组?

标准中的所有可复制或可移动类型也是如此(这些几乎是所有类型,例如vectors,sets等等),除了少数例外。例如 std::arrays 不会从移动中获益。它们花费的时间与元素的数量成正比。在那里,您可以将其退回unique_ptr以避免复制。

typedef std::array<int,15> MyArray;
std::unique_ptr<MyArray> getArray(){ 
  std::unique_ptr<MyArray> someArrayObj(new MyArray());
  someArrayObj->at(3)=5;
  return someArrayObj;
}

int main(){
  auto x=getArray();
  std::cout << x->at(3) <<std::endl; // or since we know the index is right: (*x)[3]
}

现在,为了避免再写new(除了极少数情况下的专家),您应该使用一个名为make_unique. 这将极大地帮助异常安全,并且同样方便:

std::unique_ptr<MyArray> getArray(){ 
  auto someArrayObj=make_unique<MyArray>();
  someArrayObj->at(3)=5;
  return someArrayObj;
}

要获得更多动力和(非常短的)实现make_unique,请看这里: make_unique and perfect forwarding

更新

现在make_unique是 C++14 标准的一部分。如果你没有,你可以从STL 的提案中找到并使用整个实现:

关于如何做到这一点的 Ideone 示例

于 2012-11-03T22:04:29.247 回答
4

在 C++ 中,我的方法应该返回对象还是指向对象的指针?

您应该默认返回一个对象。通常的例外是返回给定类的子类的函数,并且当不返回任何内容时是函数1的合法选项。

如果是运营商呢?

运算符返回引用或对象;尽管从重载运算符返回指针在技术上是可行的,但通常不会这样做。

还有一件事 - 如果指针变成一个向量,我如何在返回后找出它的大小?

我认为您的意思是array而不是vector,因为std::vector有一个size()返回向量大小的成员函数。确实不可能找到变长数组的大小。

如果不可能,正如我认为的那样,我应该如何在没有这个限制的情况下正确返回一个数组?

您应该使用std::vector,它不会限制您进入其中的元素的大小或类型。


1在这种情况下,您返回NULLnullptr在 C++11 中。

于 2012-11-03T22:10:45.910 回答
2

除非有特定的理由使用普通指针,否则总是返回一些内存安全的东西。在大约 95% 的情况下,简单地返回对象就可以了,然后按值返回绝对是规范的做法(简单、高效、好!)。

剩下的 5% 主要是返回的对象是运行时多态的;这样的对象不能在 C++ 中按值返回,因为这会发生在堆栈上。在这种情况下,您应该返回一个指向新对象的智能指针std::unique_ptr,在 C++11 中,标准选择是. 还有一种情况是您希望有选择地返回某些东西,但这是 IMO 特定容器的情况,而不是指针boost::optional类似的情况

于 2012-11-03T22:10:49.437 回答