2012-07-03 42 views
1

我有这实际上是指向一个派生类这样C++通过引用传递对象和铸造

Base *b = new Derived() 

我想知道的基类的一个目的,是有可能通过基类指针通过引用一些可以将对象转换回Derived类的函数。这样

Dummy_cast_fn(&b) // casts b to derived class 

什么叫Dummy_cast_fn后,b应该有派生类(无切片)的完整副本。

编辑 我不明白自指针使用以来没有切片的部分。我的问题是Derived类从函数调用返回到共享库,并且我无权访问Derived的.h文件。我仅有的信息是Derived基于Base类。我有权访问Base.h,因此我可以实例化一个Base对象,但是当我尝试访问在Derived中定义的函数但不在Base中时出现问题。所以我想知道是否可以对基类派生类型进行类型转换,然后我将能够访问在Derived中定义的函数,而不是在Base中。

+0

你想要一个完整的副本,或对原始的引用? – justin

+0

除非您将指针存储在某处,否则为什么您要通过指针?相反,通过引用传递... –

+0

我想要Derived的完整副本。 –

回答

3

只要b是一个指针或引用Derived,你总是可以:

  1. 向下投送到Derived
  2. 只要您使用b,就可以将其视为Base

即,b是什么决定了它的静态类型,在这种情况下是Base。但是,由于它实际上指向了Derived,因此可以始终向下转发它。但是,要将其用作Derived,则必须具有类型为Derived的变量。

因此,如果Dummy_cast_fn的目的只是为了解决b中的某些问题 - 这是无用的。如果一个对象被切片,没有任何东西可以修复它。但在你的情况下,没有切片,因为你正在使用指针。

根据问题的编辑编辑:

首先,你Derived对象未切片。让我们从桌子上拿下。你有一个指向完整的Derived的指针(假设这是你通过的),但是当你使用指针Base时,你只能访问它的Base部分。现在,你说你没有Derived的定义。这意味着你将无法向这种类型转型,因为编译器不知道它是如何定义的。没有铸造将在这里工作。如果您没有Derived的定义,则没有合法的C++方式可以调用sum函数。

我不明白为什么Derived的作者为您提供了它的文档而没有提供它的定义。有了这种多态性,提供者通常会让用户拥有一些“接口”,将实际类型留作内部实现细节。如果因为您没有定义而无法使用Derived,那么让您拥有其文档没有意义。

+0

我设法得到了一些关于此的更多信息。整个想法是构建一个插件系统,它可以从共享库调用插件,而不包含.h文件,因此当系统添加新插件时不需要重新编译。将插件视为功能,可以通过解析子目录列表来添加和加载功能,以查找必须加载哪些功能。所有插件都将基于定义可用的基类。把它看作是类似于用Java或Python导入的东西...... –

+0

@VivekKhurana,这正是为什么只提供'Base'的原因。这是插件界面,这是用户应该知道的唯一一件事。该插件如何提供功能是该插件的业务。如果'sum'方法应该是插件功能的一部分,它应该被添加到'Base'中。请注意,如果导入的类不可用,则Java的导入将不起作用。唯一的区别是在Java中有反射,它可以绕过定义并调查未知类型。你在C++中没有。 – eran

2

你不能改变一个Base*Derived*,但你可以得到一个Derived*指向一个Base*所指向的对象,使用dynamic_cast

Derived* d = dynamic_cast<Derived*>(b); 
if (d) { 
    // cast was succesful 
} else { 
    // cast failed, 
    // e.g. because b* does not point to a Derived* but some other derived type 
} 
2

你不能改变你的Base* b的类型,你可以创建一个新的指针

Derived* p = static_cast<Derived*>(b); 

并使用它。一旦b被宣布为Base*,您无法修改其类型。您也可以使用dynamic_cast,虽然这比较慢并且可能不是必须的(尽管我不能肯定地说 - 这取决于您的要求)。如果您正确使用虚拟功能,你甚至可以不需要做任何造型 - 这是多态

的目的之一