[英]C++ equivalent for simple Java polymorphism
I'm struggling with a seemingly simple task in C++. 我正在努力克服C ++中看似简单的任务。 I'm trying to achieve basic OOP polymorphism.
我正在尝试实现基本的OOP多态性。
Consider this Java example: 考虑这个Java示例:
interface Bob
{
void foo();
}
class ActualBob implements Bob
{
void foo()
{
/* I like foo things */
}
}
class Jane
{
Bob bob;
}
Jane can have any Bob, easypeasy: 简可以有任何鲍勃,很容易:
Jane jane = new Jane();
jane.bob = new ActualBob();
jane.bob.foo(); // actualbob things
Now, in C++ this seems somewhat more involved.... What do I have to type to get the above behaviour? 现在,在C ++中,这似乎有点涉及......我需要输入什么来获得上述行为?
In other words, I would like to have member variables of an abstract base class, but would like to do actual-implementation things with them. 换句话说,我想有一个抽象基类的成员变量,但是想用它们做实际的实现。
class Bob
{
public:
virtual void foo() = 0;
}
class ActualBob : public Bob
{
public:
void foo(){/* I like foo things */}
}
class Jane
{
public:
Bob bob;
}
Taking shortcuts here, but I'd like to do, in C++: 在这里采取捷径,但我想用C ++做:
jane.bob.foo(); // does ActualBob things
Also, can I have a std::vector<Bob>
which contains ActualBob
instances? 另外,我可以有一个包含
ActualBob
实例的std::vector<Bob>
吗?
Use pointers, smart pointers, like this: 使用指针,智能指针,如下所示:
class Bob
{
public:
virtual void foo() = 0;
}
class ActualBob : public Bob
{
public:
void foo() override {/* I like foo things */}
}
class Jane
{
public:
std::unique_ptr<Bob> bob;
}
Taking shortcuts here, but I'd like to do, in C++:
在这里采取捷径,但我想用C ++做:
jane.bob.foo(); // does ActualBob things
You can do this: 你可以这样做:
jane.bob->foo(); // does ActualBob things, if `bob` is a pointer to ActualBob
Also, can I have a
std::vector<Bob>
which containsActualBob
instances?另外,我可以有一个包含
ActualBob
实例的std::vector<Bob>
吗?
Yes, with some modifications, you can have a std::vector<Bob*>
(but you must free memory on your own) or, better, some smart pointers, like std::vector<std::unique_ptr<Bob>>
. 是的,通过一些修改,你可以有一个
std::vector<Bob*>
(但你必须自己释放内存),或者更好的是,一些智能指针,比如std::vector<std::unique_ptr<Bob>>
。
Your code would be fine if Bob
were non-polymorphic: 如果
Bob
是非多态的,那么你的代码就可以了:
class Jane
{
public:
Bob bob;
};
However, trying to store a polymorphich object in bob
would lead to object slicing , which drops polymorphism. 但是,尝试在
bob
存储多态对象会导致对象切片 ,从而丢弃多态。 In order to preserve it, use a pointer or a reference to Bob
. 为了保留它,请使用指针或
Bob
的引用。
Depending on the ownership of Bob
you could use a different kind of pointer, or even a reference. 根据
Bob
的所有权,您可以使用不同类型的指针,甚至是引用。 For example, if Bob
is allocated dynamically, and could be shared among multiple instances of Jane
, using std::shared_ptr<Bob>
would be appropriate: 例如,如果
Bob
是动态分配的,并且可以在Jane
多个实例之间共享,则使用std::shared_ptr<Bob>
是合适的:
class Jane
{
public:
Jane(Bob* bPtr) : bob(bPtr) {}
std::shared_ptr<Bob> bob;
};
You nearly have it. 你几乎拥有它。 The problem is that it seems in Java that you don't have to use anything in order to create a polymorphic object, while actually in Java all that variables are references.
问题是,在Java中,您似乎不必使用任何东西来创建多态对象,而实际上在Java中所有变量都是引用。 Java references are C++ pointers with less capabilities.
Java引用是具有较少功能的C ++指针。
In C++, when you type Bob bob;
在C ++中,键入
Bob bob;
, you're actually creating an object of the precise type on the left. ,你实际上是在左边创建一个精确类型的对象。 When you use a pointer instead, then at the right you can have a Bob object (which would be impossible in this case, since the class Bob has a pure virtual method), or any other subclass.
当您使用指针时,在右侧,您可以拥有一个Bob对象(在这种情况下这是不可能的,因为Bob类具有纯虚方法)或任何其他子类。
So, in your code: 所以,在你的代码中:
class Jane
{
public:
Jane()
{ bob = new ActualBob(); }
Bob * bob;
}
We have, however, run into a different, dangerous scenario without warning. 但是,我们在没有任何警告的情况下遇到了另一种危险的情况。 Java has a garbage collector, basically meaning that any object which is not referenced is deleted.
Java有一个垃圾收集器,基本上意味着删除了任何未引用的对象。 This is not done automatically in C++, so we have to do it manually, using the
delete
operator. 这不是在C ++中自动完成的,因此我们必须使用
delete
运算符手动完成。 Or maybe a smart pointer in this case: they behave in C++ doing the deletion of the object automatically. 或者在这种情况下可能是智能指针:它们在C ++中表现自动删除对象。 We have
std::unique_ptr<>
available, doing exactly that. 我们有
std::unique_ptr<>
可用,正是这样做的。 There are indeed other scenarios, such as copying Jane objects, which are somewhat managed by a smart pointer. 确实存在其他方案,例如复制Jane对象,这些对象在某种程度上由智能指针管理。 So instead of talking about rules (destructors, copy constructors, operator assignment, and family), let's use one of them:
因此,不要谈论规则 (析构函数,复制构造函数,运算符赋值和族),而是使用其中一个:
class Jane
{
public:
Jane()
{ bob.reset( new ActualBob() ); }
unique_ptr<Bob> bob;
}
The unique_ptr<>
smart pointer captures the use of ->
(technically, it has the arrow operator overloaded), so its use is syntactically familiar to the use of a regular pointer. unique_ptr<>
智能指针捕获使用->
(技术上,它有箭头操作符重载),因此它的使用在语法上熟悉常规指针的使用。 Now: 现在:
Jane jane = new Jane();
jane.bob->foo();
Also, can I have a
std::vector<Bob>
which contains ActualBob instances?另外,我可以有一个包含ActualBob实例的
std::vector<Bob>
吗?
Sure, but have to change your code in the same way as above: you would have to use std::vector<Bob *>
, and free the objects pointed by the members yourself. 当然,但必须以与上面相同的方式更改代码:您必须使用
std::vector<Bob *>
,并自行释放成员指向的对象。 Or, you could use again a smart pointer, as in: std::vector<unique_ptr<Bob>>
. 或者,您可以再次使用智能指针,如:
std::vector<unique_ptr<Bob>>
。
Hope this helps. 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.