使用基类指针来派生类 [英] use base class pointer for derived classes

查看:55
本文介绍了使用基类指针来派生类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





想象一下,我有一些基类动物。

来自它的派生类,比如Cat。



是否可以做smth。像这样:

想象一下我有一个函数需要一个指针

到Animal对象。



  void  func(Animal * p)
{

}



现在,我用一个指向Cat类的指针来调用

这个函数而不是指向Animal对象的指针。例如



 Cat * cat =  new  Cat; 
func(cat);





现在,在 func 内函数,我希望能够在传递的 cat 指针上调用Cat类方法。可能吗?怎么样?

谢谢。

解决方案

这是学习OOP的关键步骤,然后再接近它的核心 - 虚函数和后期绑定。



这是一个想法:派生类与其基类兼容:

 < span class =code-keyword> class 动物{ / *   ... * / }; 
class Cat: public 动物{ / * ... * / };

Cat * cat = new Cat();
动物*动物=猫; // 但在一般情况下不可能相反





这不是很明显吗?假设您从 Animal 中缺少 Cat 的成员。



如果您将指向 Cat 的指针指向 Animal 的指针,您将可以访问此非现有成员,会使申请崩溃,但上面显示的相反情况很好。



从这个简单的考虑可以推断出你的问题的答案。您在 Animal 中的 func 中使用编译时类。由于 Cat 是动物,使用它作为运行时类很好:无论这个函数做什么,它都将与成员和实例一起运行 Cat 总是有。



-SA


好的,您已经发现,Cat可以被视为Animal对象。这称为向上转换,由编译器自动完成,因为它并不危险。



另一个方向需要一些特殊的知识。你有一个Animal指针,你知道底层对象是一个Cat对象。在这种情况下,您可以像这样执行向下转换:



 Cat * pCat = dynamic_cast< Cat *> (pAnimal); 





动态强制转换运算符将传递NULL指针,以防pAnimal指向Cat。请注意,这需要在编译器中启用RTTI(运行时类型信息)。



你也可以做一个普通的老演员

< pre lang =c ++> Cat * pCat =(Cat *)pAnimal;



这是相对危险的,因为如果pAnimal没有指向Cat,你就不会收到警告信号。不推荐这样做!


是的可能。 C ++最好的一面是向下转换和向上转换。

向下转换是指从Base类将对象更改为派生类之一。向上倾斜是相反的事情。结合虚拟功能,它真的很有用。如果您有基类Shape和一些其他子类,如Triangle,Circle等。当您键入某个函数时,您不需要检查对象的类型,您可以创建有关Base类的函数。它也适用于所有的儿童课程。这是虚拟功能的用武之地。即使您在执行虚函数时将项目向上移动到基类,也会执行正确的项目(意味着在对象的子类中定义的项目)而不是基础项目,除非对象来自那个班。

这可以帮助您创建更少检查的功能,更容易维护。



一个提示:向下倾斜可能是棘手和危险的。当你这样做时使用dynamic_cast。如果对象无法下载到子类,则此函数将返回NULL。通过简单检查对象是否与NULL不同,您可以省去许多麻烦:)


Hi,

Imagine I have some base class Animal.
And a derived class from it, say Cat.

Is it possible to do smth. like this:
Imagine I have a function which expects a pointer
to Animal object.

void func(Animal * p)
{

}


Now, instead of a pointer to Animal object, I call
this function with a pointer to Cat class. e.g.

Cat * cat = new Cat;
func(cat);



Now, inside the func function, I want to be able
to call Cat class methods on the passed cat pointer. Is it possible? And how?
Thanks.

解决方案

This is the key step in learning OOP before you approach the heart of it — virtual functions and late binding.

Here is the idea: derived class is assignment compatible with its base class:

class Animal {/* ... */};
class Cat : public Animal {/* ... */};

Cat* cat = new Cat();
Animal* animal = cat; // but the opposite is not possible in general case



Isn''t that apparent? Suppose you have some member of Cat missing from Animal.

If you assign a pointer to Cat to a pointer to Animal, you will get access to this non-existing member, which would "crash" the application, but the opposite case shown above is fine.

The answer to your question is inferred from this simple consideration. You compile-time class used in func in Animal. As Cat is animal, using it as a run-time class is fine: whatever this function does, it will operate with the members and instance of Cat always has.

—SA


Ok, you have found out, that a Cat can be treated as an Animal object. That''s called up-casting and that is done automatically by the compiler, as it is not dangerous.

The other direction requires some special knowledge. You have an Animal pointer and you "know" that the underlying object is a Cat object. You can in this instance perform a down-cast like this:

Cat* pCat = dynamic_cast<Cat*> (pAnimal);



The dynamic cast operator will deliver a NULL pointer, in case pAnimal does not point to a Cat. Note that this requires RTTI (runtime type information) to be enabled in your compiler.

You also could do a plain old cast

Cat* pCat = (Cat*) pAnimal;


which is however relatively dangerous, as you do not get a warning sign in case pAnimal does not point to a Cat. Not the recommended way to do it!


Yes its possible. One of the best sides of C++ is the downcasting and upcasting.
Downcasting is when from the Base class you change your object to one of the derived classes. The Upcasting is the opposite thing. Combined with virtual functions its really powerful thing. If you have base class Shape and some other child classes like Triangle, Circle and so on . When you type some function you don''t need to check what type your object is, you can make the function about the Base class. And it will be working for all the child classes too. This is where the virtual functions kick in . Even when you upcast your item to the base class when you are about the execute of the virtual functions the right one will be executed(meaning the one defined in the child class of the object) and not the base one except if the object is from that class.
This helps you create functions with less checks which are easier to maintain.

One tip : Downcasting can be tricky and dangerous . When you do it use dynamic_cast. If the object cant be downcasted to the child class this function will return NULL. With simple check if the object is different from NULL you can save yourself many troubles :)


这篇关于使用基类指针来派生类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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