C++ 返回C+中的类+;
在Java中,所有类实际上都是引用,我这样做: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
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; }