Для типов примитивов это нормально:
int inc(int x) {
return x+1;
}
для более сложных типов, чтобы избежать дополнительного копирования при возврате функции
void reverse_vector(const std::vector<int>& v, std::vector<int>* result) {
if (!result) return;
*result = v;
std::reverse(result->begin(), result->end();
}
// ...
std::vector<int> v;
std::vector<int> reversed;
reverse_vector(v, &reversed);
Для объекта, выделенного из кучи, я предлагаю использовать библиотеку boost :: shared_ptr (tr1 :: shared_ptr). Тогда вы можете кодировать почти так же, как в Java.
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
class A {
public:
A(int x, const std::string& str)
: x(x), str(str) {
}
void foo() {
}
private:
int x;
const std::string& str;
};
// ...
boost::shared_ptr<A> a = boost::make_shared<A>(1, "hello");
a->foo();
Вы можете рассматривать объекты boost :: shared_ptr как ссылки на java. Сборка мусора отсутствует (просто подсчет ссылок), поэтому вы должны позаботиться о циклах самостоятельно.
Имейте в виду, что shared_ptr немного медленнее стандартного указателя.
Также важно помнить, что вам следует избегать копирования больших объектов. Лучше написать
void foo(const std::string& str);
вместо
void foo(std::string str);
если вам не нужна копия str в foo.
Еще одна вещь - это то, что компилятор умен и сделает некоторые оптимизации для вас. Например, reverse_vector может быть записан как
std::vector<int> reverse_vector(std::vector<int> v) { // note copying!
std::reverse(v.begin(), v.end());
return v; // no additional copying of temporary due to RVO
}
Это RVO (оптимизация возвращаемого значения) очень полезно, но иногда компилятору не удается сделать это автоматически. Вот почему я бы предложил писать такого рода функции, не полагаясь на RVO, если только вы не узнаете, когда он не работает.