Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 返回C+中的类+;_C++_Object - Fatal编程技术网

C++ 返回C+中的类+;

C++ 返回C+中的类+;,c++,object,C++,Object,在Java中,所有类实际上都是引用,我这样做: Car getCar(int mileage) { Car car = new Car(); car.setMileage(mileage); return car; } 在C++中,我该怎么做?我可以把它放在参考书中: void getCar(int mileage, Car& car) { car.setMileage(mileage); return true; } 或者,我可以创建一个新对象: Car* g

在Java中,所有类实际上都是引用,我这样做:

Car getCar(int mileage)
{
  Car car = new Car();

  car.setMileage(mileage);
  return car;
}
在C++中,我该怎么做?我可以把它放在参考书中:

void getCar(int mileage, Car& car)
{
  car.setMileage(mileage);
  return true;
}
或者,我可以创建一个新对象:

Car* getCar(int mileage)
{
  Car* car = new Car;

  car.setMileage(mileage);
  return car;
}
但是,调用方还负责删除
car

我不想返回指针。我想退车:

Car getCar(int mileage)
{
  Car car;

  car.setMileage(mileage);
  return car;
}
当然,
car
是一个局部变量,一旦函数完成,它就会被删除


通常的“标准”方法是什么?哪种方法是最好的,为什么?

最后一个示例是返回对象的正确且惯用的方法:

Car getCar(int mileage)
{
  Car car;

  car.setMileage(mileage);
  return car;
}
是,
car
将在函数结束时删除,但不会在复制到返回对象之前删除。您可以这样调用此函数:

{
    Car myCar;
    myCar = getCar(42);
}
getCar
本地的
car
被复制到调用环境的
myCar


您不能也不能返回对局部变量的引用或指针。 这是错误的:

Car& getCar(int mileage)
{
  Car car;
  return car;
}
这也是错误的:

Car* getCar(int mileage)
{
  Car car;
  return &car;
}
在每种情况下,您都允许调用函数访问不再存在的对象


您不能返回指向本地的指针或引用。您可以返回本地文件的副本

您的最后一段代码很好——您返回的是局部变量的值,而不是局部变量本身,因此(至少在理论上)该值将从局部变量复制到调用方分配它的任何位置

这基本上就像我有这样的东西:

int f() { 
    int x = 0; 
    return x;
}
我们再次返回一个值。值恰好来自一个局部变量,但我们仍然返回值,而不是变量

就“至少在理论上”而言,大多数编译器都可以对此进行优化,这样就根本不会发生复制。有一些特殊的规则允许编译器跳过此复制,即使复制会产生外部可见的副作用,而这些副作用在复制发生时是您希望看到的(例如,如果您编写了一个复制构造函数,在复制发生时打印出某些内容)

在C++中,我该怎么做?我可以把它放在参考书中:

void getCar(int mileage, Car& car)
{
  car.setMileage(mileage);
  return true;
}
是-这没关系,不过对于
void
函数,您不能返回任何内容

或者,我可以创建一个新对象:

Car* getCar(int mileage)
{
  Car* car = new Car;

  car.setMileage(mileage);
  return car;
}
但是,打电话的人也要负责删除汽车

没错。。。但您可以使用智能指针使其更加可靠和方便

我不想返回指针。我想退车:

Car getCar(int mileage)
{
  Car car;

  car.setMileage(mileage);
  return car;
}
当然,car是一个局部变量,一旦函数完成,它就会被删除

不正确-这非常有效-car对象是通过值返回的,这意味着调用方可以在堆栈上使用它来表示表达式,包括作为复制其他地方的源

通常的“标准”方法是什么?哪种方法最好,为什么


一般来说,上面的最后一个版本是“标准”方式——它通常足够有效(通常是优化构建的最佳方式),避免了混乱的指针,而且直观简单。当然,从C++中,你可以在java上执行java代码。在这里,你需要<代码>新< /COD>变量在整个地方都是痛苦的。

< P>重要的区别是,在Java对象中引用,并用它们的地址来标识。< /P> 在C++中,它们是“值”(如<代码> int >代码>)和…由地址标识:-((这是规范如何调用要创建的对象)

不管成语怎么说,你都必须做出决定:什么对你重要:价值还是地址

两个
具有相同的
姓名
值,表示一个相同的人(在现实世界中)或两个真实的单词同名词Person-s?多态性在您的上下文中有多重要?(是否有许多类型的“Person-s”由不同的
表示)

这不是“习语”所说的,而是你必须建立的惯例

如果您想使用值,请按值返回(注意:在大多数情况下,编译器会忽略返回时复制,因此它不是性能限制),但请忘记多态性。但是如果您的对象包含一些资源,请确保它们也遵循“按值”范型,否则准备重写构造函数、析构函数、复制构造函数、移动构造函数和赋值,以正确处理资源所有权。或者…使用按值资源管理器来包装它们(智能指针可以做到这一点)

如果您想使用地址,并且需要多态性,那么就要准备好在堆上分配对象、使用指针,并正确地管理分配/解除分配(最终要借助智能指针,如
unique\u ptr
shared\u ptr

对于这两种情况,都有一系列的习惯用法和模式,但第一点是理解您的目标是什么模型,并且行为一致


<>但是无论如何你都得不到:C++永远不会像java一样。所以不要试图仿效它。按值或指针(引用没有改变很多)。您必须换一种方式思考。

您的上一个示例非常好-它返回了一个汽车的副本。当函数返回时,原始汽车被删除对该副本没有影响。粗略地说,它相当于您的原始Java示例更改为
return car.clone()
(如果
clone
Car
上公开).作为奖励,即使它应该返回一个副本,但大多数情况下它实际上不是。等等,为什么添加了该子句?在我看来,这只会造成更多的歧义。等等,你是认真的吗?我一直在想…没关系。看起来我错了!有没有办法确保编译器不会进行复制(任何编译器)?我有一个类似的例子,在函数
a
中,我正在创建一个新的o
Car getCar(int mileage) {   Car car;    car.setMileage(mileage);   return car; }