[英]A Request for Simple C++ Composition vs. Inheritance Examples
I am trying to understand the syntactic difference between composition and inheritance in C++.我试图了解 C++ 中组合和继承之间的语法差异。
I'm hoping someone will provide two simple examples.我希望有人能提供两个简单的例子。 One example of a class that uses composition and one of a class that uses inheritance.
一个使用组合的类和一个使用继承的类的例子。
Sure, why not?当然,为什么不呢? Since I like robots, let's make a robot that can walk around and grab things.
既然我喜欢机器人,那就让我们做一个可以四处走动和抓取东西的机器人吧。 We'll make one robot using inheritance, and another robot using composition:
我们将使用继承制作一个机器人,并使用组合制作另一个机器人:
class Legs
{
public:
void WalkAround() {... code for walking around goes here...}
};
class Arms
{
public:
void GrabThings() {... code for grabbing things goes here...}
};
class InheritanceRobot : public Legs, public Arms
{
public:
// WalkAround() and GrabThings() methods are implicitly
// defined for this class since it inherited those
// methods from its two superclasses
};
class CompositionRobot
{
public:
void WalkAround() {legs.WalkAround();}
void GrabThings() {arms.GrabThings();}
private:
Legs legs;
Arms arms;
};
Note that at least for this example, the CompositionRobot
is usually considered to be the better approach, since inheritance implies an is-a
relationship, and a robot isn't a particular kind of Arms
and a robot isn't a particular kind of Legs
(rather a robot has-arms
and has-legs
).请注意,至少在这个例子中,
CompositionRobot
通常被认为是更好的方法,因为继承意味着is-a
关系,并且机器人不是特定种类的Arms
,机器人也不是特定种类的Legs
(而不是机器人has-arms
和has-legs
)。
To expand a little on @jeremy-friesner's answer (and mostly reuse his code), a lot of the time composition is implemented using more classes than that.为了稍微扩展@jeremy-friesner 的答案(并且主要是重用他的代码),很多时候使用比这更多的类来实现组合。 Essentially the Legs and Arms classes would be implementations of an interface.
Legs 和 Arms 类本质上是接口的实现。 This makes it easy to inject those dependencies and, hence, mock/stub them out when unit testing the composite object.
这使得注入这些依赖项变得容易,因此在对复合对象进行单元测试时模拟/存根它们。 Then you'd have something like (ignoring virtual destructor...) :
然后你会有类似的东西(忽略虚拟析构函数......):
class Walker // interface
{
public:
virtual void Walk() = 0;
}
class Legs : public Walker
{
public:
void Walk() {... code for walking around goes here...}
}
class Grabber // Interface
{
public:
virtual void GrabThings() = 0;
}
class Arms : public Grabber
{
public:
void GrabThings() {... code for grabbing things goes here...}
}
class InheritanceRobot : public Legs, public Arms
{
public:
// Walk() and GrabThings() methods are implicitly
// defined for this class since it inherited those
// methods from its two superclasses
};
class CompositionRobot
{
public:
CompositionRobot(Walker& walker, Grabber& grabber)
: legs(walker),
arms(grabber)
{}
void Walk() {legs.Walk();}
void GrabThings() {arms.GrabThings();}
private:
Walker& legs;
Grabber& arms;
};
So the actual implementation used for legs and arms could be set at run-time instead of compile time.因此用于腿和手臂的实际实现可以在运行时而不是编译时设置。
As an aside, I only wrote this as an answer, rather than a comment on Jeremy's answer, to benefit from the code formatting so, if you feel like up-voting it, please do Jeremy's too.顺便说一句,我写这个只是作为一个答案,而不是对 Jeremy 的答案的评论,以便从代码格式中受益,因此,如果您想对它进行投票,请也做 Jeremy 的。
HTH HTH
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.