c ++对象参数:多态性,值语义,对象生命周期? [英] c++ Object parameters: polymorphism, value semantics, object lifetimes?

查看:238
本文介绍了c ++对象参数:多态性,值语义,对象生命周期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从C#转换到C ++时,我得到了很多建议,尽可能使用价值语义。它几乎保证,如果我发布一个指针,任何地方的人会来的建议,它应该是一个值的问题。我开始看到光,我发现了很多地方在我的代码中,我可以替换动态分配和指针与堆栈分配的变量(通常引用)。所以我认为我已经掌握了使用堆栈分配的对象,并将其传递给其他函数作为引用,当对象的生命周期在调用程序比被调用方更长时。

As I make the transition from C# to C++ I get a lot of recommendations to use value semantics where possible. It's pretty much guaranteed that if I post a question with a pointer anywhere someone will come along and suggest that it should be a value instead. I'm starting to see the light and I have found a lot of places in my code where I could replace dynamic allocation and pointers with stack allocated variables (and usually references). So I think I have a grasp on using stack allocated objects and passing them to other functions as references when the object lifetime is longer in the caller than the callee.

但是,有一个问题,当被调用者将拥有所有权时,通过值传递对象。以下例为例:

However I have a question about passing objects by value when the callee will take ownership. Take the following example:

class Zoo
{
  void AddAnimal(Animal animal);
  std::list<Animal> animals_;
}

通常从灵活性和单元测试的角度来看,我想让Animal成为接口(在C ++中的抽象类),所以我可以很容易地发送任意的动物,并用模拟实现模拟它。

Typically from a flexibility and unit testing perspective I'd want Animal to be an interface (abstract class in C++) so I can easily send arbitrary animals and mock it out with a mock implementation.

在指针实现客户端代码将调用这样:

In a pointer implementation client code would be calling this like:

Animal animal = new Lion("Bob");
myZoo.AddAnimal(animal);

这里的客户端代码不需要动物对象。它只是临时构造它传递给方法。所以在这种情况下没有共享语义。所以它似乎是值语义的一个好例子。然而,我的理解是,你不能使用Animal作为通过值的参数,因为它是一个抽象类。

Here the client code doesn't really need the animal object. It's just constructing it temporarily to pass to the method. So in this case there aren't shared semantics. So it seems like a good case for value semantics. However, my understanding is that you can't use Animal as a parameter passed by value because it's an abstract class.

大多数成员函数不采取原始类型采用抽象类参数。那么什么是C ++方法来处理这个问题呢? (这是你如何使用值语义对C ++中的接口进行编程)

Most of my member functions that don't take primitive types take abstract class parameters. So what is the C++ method to handle this problem? (That is how do you program to interfaces in C++ with value semantics?)

推荐答案

资源管理处理程序对象,您可以通过值传递 。热门候选人包括 shared_ptr unique_ptr

The typical solution for your scenario would involve a resource-managing handler object which you do pass by value. Popular candidates are shared_ptr and unique_ptr:

#include <list>
#include <memory>
#include "all_zoo_animals.h"  // yours

typedef std::shared_ptr<Animal> AnimalPtr;  // see note
typedef std::list<AnimalPtr> AnimalCollection;

AnimalCollection zoo;

void addAnimal(AnimalPtr a)
{
  zoo.push_back(a);
}

int main()
{
  AnimalPtr a = AnimalPtr(new Penguin);
  a.feed(fish);
  addAnimal(a);  // from local variable, see note

  addAnimal(AnimalPtr(new Puffin)); // from temporary
}

如果可行,也可以定义 AnimalPtr as std :: unique_ptr< Animal> ,但是你必须说 addAnimal move(a)); 。这是更加限制性的(因为在任何给定时间只有一个物体处理动物),而且重量更轻。

If it is feasible, you could also define AnimalPtr as std::unique_ptr<Animal>, but then you have to say addAnimal(std::move(a));. This is more restrictive (as only one object handles the animal at any given time), but also lighter-weight.

这篇关于c ++对象参数:多态性,值语义,对象生命周期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆