简体   繁体   English

C ++键入和OOP子类

[英]C++ Typing and OOP child classes

I'm a bit confused: 我有点困惑:

  • If I have a base class A, and a class B which extends A, can a variable of the type A hold a value of the type B and vice versa? 如果我有一个基类A和一个扩展了A的类B,那么类型A的变量可以保存类型B的值,反之亦然吗?

If yes, why? 如果是,为什么? Aren't they completely different even if B is derived from A? 即使B衍生自A,它们也不完全不同吗? How about type-safety? 类型安全怎么样?

  • If this is possible, what things do I have to mind when taking use of this? 如果可能的话,使用此功能时我要注意些什么? How would this work out in terms of performance? 在性能方面这将如何解决?

Note: Sorry if I asked too many questions, just ignore them and just look out for those "marked" with the list decoration dot :) Also, this is not my homework. 注意:很抱歉,如果我问了太多问题,请忽略它们,只寻找那些带有装饰点的“标记” :)另外,这不是我的作业。 I'm a hobby programmer and have skills in scripting languages with OOP, yet I'm relatively new to OOP typing in C++. 我是一名业余程序员,并且具有使用OOP编写脚本语言的技能,但是对于使用C ++进行OOP键入我还是比较陌生。

If you do this: 如果您这样做:

B b;
A a = b;

then you get "slicing". 然后您会得到“切片”。 a will contain just the A part of b . a将仅包含bA部分。

But you can have references/pointers: 但是您可以具有参考/指针:

B b;
A &ra = b;
A *pa = &b;

In this case, ra and pa just refer/point to the real B object. 在这种情况下, rapa仅引用/指向实数B对象。 This is because public inheritance models an IS-A relation. 这是因为公共继承为IS-A关系建模。 This is easier to understand with more descriptive names. 使用更具描述性的名称更容易理解。 Think of A and Animal and B as Baboon . 认为AAnimal BBaboon A Baboon IS-A Animal so by using references/pointers, you can treat a Baboon as it's more generic Animal type. Baboon IS-A Animal因此,通过使用引用/指针,您可以将Baboon视为更通用的Animal类型。

A variable of type A can hold a value of type B (for certain definitions of "hold", as other answers explain), but definitely not vice-versa. 类型A的变量可以保存类型B的值(对于“ hold”的某些定义,如其他答案所解释),但绝对不能相反。 To break out a standard example: 举一个标准的例子:

class Animal {};
class Dog : public Animal {};
class Cat : public Animal {};

This is legal, because Cat derives from Animal : 这是合法的,因为Cat源自Animal

Cat c;
Animal& a = c;

This isn't: 这不是:

Animal a;
Cat& c = a;

This is type-safe because you've defined it to be so; 这是类型安全的,因为您已经定义了它。 the whole point of inheritance is to allow this sort of thing to happen, so you can go on to call methods on a generic Animal variable without knowing what base class happens to be stored in it. 继承的全部要点是让这种事情发生,因此您可以继续调用通用Animal变量上的方法,而无需知道将在其中存储什么基类。 As for the performance question, calling virtual methods is slower because deciding which method will actually be called ( Cat::foo() versus Dog::foo() , for example, depending on the particular type of Animal stored in the variable) has to happen at run-time -- this is called dynamic dispatch . 至于性能问题,调用虚拟方法的速度较慢,因为决定实际调用哪个方法Dog::foo()例如,取决于存储在变量中的Animal的特定类型,例如Cat::foo()Dog::foo() )在运行时发生-这称为动态调度 With non-virtual methods the decision can happen at compile time 使用非虚拟方法时,决策可以在编译时发生

A pointer or reference to an object of class A can point/refer to an object of class B . 指向引用A的对象的指针引用可以指向/引用类B的对象。 That's because if B derives from A , then a B is-a A . 这是因为,如果B衍生自A ,则B A Each object of class B has all the member variables and functions of class A , plus those unique to B . 类的每个对象B具有所有成员变量和类函数A ,加上那些特有的B

class A
{
   public:
      virtual ~A();
      void foo();
};

class B : public A
{
   public:
      void bar();
};

A * a = new B;
a->foo(); // perfectly valid, B inherits foo() from A
//a->bar(); // compile-time error, bar() is only defined in B
delete a; // make sure A has a virtual destructor!

Usually, this sort of code is used when you want to make use of polymorphic behavior through virtual functions. 通常,当您想通过虚函数使用多态行为时,会使用这种代码。

Not to be contrary, but performance is not the right question here. 不必矛盾,但是性能并不是这里的正确问题。 If you've decided that you're going to make an OO design, don't sacrifice the correct abstraction for performance concerns. 如果您决定要进行OO设计,请不要为性能问题而牺牲正确的抽象。 Premature optimization is the root of all evil. 过早的优化是万恶之源。 Good luck! 祝好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM