C++ 从函数返回本地对象

C++ 从函数返回本地对象,c++,memory,function,object,reference,C++,Memory,Function,Object,Reference,这是从函数返回对象的正确方法吗 Car getCar(string model, int year) { Car c(model, year); return c; } void displayCar(Car &car) { cout << car.getModel() << ", " << car.getYear() << endl; } displayCar(getCar("Honda", 1999)); 从函数

这是从函数返回对象的正确方法吗

Car getCar(string model, int year) {
   Car c(model, year);
   return c;
}

void displayCar(Car &car) {
   cout << car.getModel() << ", " << car.getYear() << endl;
}

displayCar(getCar("Honda", 1999));

从函数返回局部变量的引用是不安全的

是的,这是正确的:

Car getCar(string model, int year) {
   Car c(model, year);
   return c;
}

getCar
按值返回一个
Car
,这是正确的

您不能将该返回值(它是一个临时对象)传递到
displayCar
,因为
displayCar
接受
Car&
。不能将临时引用绑定到非常量引用。您应该更改
displayCar
以获取常量参考:

void displayCar(const Car& car) { }
void displayCar( const Car & car ) {
   cout << car.getModel() << ", " << car.getYear() << endl;
}
Car getCar( const string & model, int year) {
或者,您可以将临时变量存储在局部变量中:

Car c = getCar("Honda", 1999);
displayCar(c);
但是,最好让
displayCar
获取常量引用,因为它不会修改对象

不要返回对本地
Car
变量的引用。

您的问题是:

void displayCar(Car &car) {
   cout << car.getModel() << ", " << car.getYear() << endl;
}
从目前的情况来看,它是可以的,但它所做的一切都是构造函数所做的,因此它是冗余的。对于这种类型的函数,返回值而不是引用是正确的做法,但是,模型参数应通过const reference传递:

void displayCar(const Car& car) { }
void displayCar( const Car & car ) {
   cout << car.getModel() << ", " << car.getYear() << endl;
}
Car getCar( const string & model, int year) {
一般来说,对于string或Car之类的类类型,参数的默认选择应该始终是常量引用。

更好的是:

Car getCar(string model, int year) { 
      return Car(model, year);  
}

是的,返回指向临时对象的引用或指针肯定不安全。当它过期时(即当函数
getCar
退出时),您将带着技术上称为“悬空指针”的东西离开


然而,如果您热衷于减少对象上的复制操作,那么应该查看C++0x的“移动语义”。这是一个相对较新的概念,但我相信它很快就会成为主流。GCC 4.4以上版本支持C++0x(使用编译器选项
-std=C++0x
启用)。

Hmm,我需要一个类似工厂函数的东西,它将创建一个对象并将其返回。许多(大多数?)编译器优化
返回汽车(型号,年份)
,这样就不需要进行额外的复制,所以我要去掉显式局部变量。@Steven:许多(大多数?)编译器也实现了命名返回值优化(NRVO),所以通常没有区别。@pocoa:您也可以通过分配一个新的实例并通过指针返回来使用动态内存。我建议使用合适的智能指针,以避免泄漏。@James:你可能是对的。上次我检查时,命名值不太可能被优化。这正是我在回答中所说的“复制操作”。虽然目前这是标准的解决方案,但它比只返回地址要昂贵得多。@themoondothshine:大多数编译器(据我所知)都会在这里执行RVO,因此这是一个非常便宜的操作。您也可以存储临时文件,而无需调用复制构造函数(发生在
Car c=getCar(…)
如果以后不需要通过
c
进行更改,请使用对const:
const-Car&c=getCar(…)
的引用。