将指向一个派生类的指针传递给另一个

时间:2015-12-30 17:43:48

标签: c++ class pointers

我还在学习c ++的基础知识,但我目前正在使用派生类和虚拟方法开展项目。所以情况是: 我有一个ClassA

class ClassA
{
public:
    virtual void action();
};

有两个派生类B和C:

#include "ClassA.h" 

class ClassB: public ClassA
{
public:
    virtual void action();
    int valueB;
};

-

#include "ClassA.h"

class ClassC: public ClassA
{
public:
    virtual void action();
    int valueC;
};

我想在ClassC中传递一个指向ClassB对象的指针作为action()的参数,所以我可以这样做:

void ClassC::action(ClassB * ptr)
{
cout << "The value is: " << ptr->valueB;
}

然而,我找不到一种有效的方法。所有对象指针都存储在

vector<ClassA *> objects

,其中

objects[0]=new ClassC();
objects[1]=new ClassB();

如果我尝试类似

的话
objects[0]->action(object[1])

然后我需要在ClassA中使用我的虚方法来获得参数ClassB *。然后让一个程序识别我试过的类型要么包括整个ClassB.h(坏主意,它创建一个&#34;循环&#34;包含什么)或使用前向声明类ClassB; (我收到有关无效使用不完整类型的错误)。所以我现在卡住了。我希望一切都很清楚,但如果需要,我当然可以提供更多数据。

3 个答案:

答案 0 :(得分:2)

当你需要转发声明的东西时,因为你不能包含整个类的定义。在这种情况下,如果您转发声明ClassB,编译器不知道其成员属性valueB,那就是您获得不完整类型错误的原因。要解决这个问题,你必须考虑类似代码:

//ClassA.h
class ClassB;

class ClassA
{
  virtual void action(ClassB* ptr);
}

//ClassA.cpp
#include "ClassB.h"
void ClassA::action(ClassB* ptr) { ... }

因此,您基本上使用标头来声明虚拟方法并转发声明ClassB,但您在ClassA.cpp中定义它,以便在源文件中包含ClassB.h没有问题,没有循环依赖的风险。

答案 1 :(得分:1)

我注意到你的ClassC虚函数被声明为不带参数:

virtual void action();

但您使用参数定义派生类函数。

void ClassC::action(ClassB * ptr)

声明和定义必须匹配。将声明更改为:

virtual void action(ClassB *);

嗯。但是,你必须在ClassC声明之前包括ClassB ......

#include "ClassB.h"

或转发声明ClassB。这是对编译器的承诺,以便稍后正确声明和定义该类。插入此行的好地方就在ClassC声明之前。

class ClassB;

答案 2 :(得分:0)

您可以将action(在所有类中)定义为:

virtual void action(ClassA * ptr); // or ClassB *

然后,您可以传递ClassA的任何实例或从ClassA派生。 所有派生类都可以包含带有#include "ClassA.h"的ClassA,如果你在头文件中提供Sentinel,因为它在c ++中很常见:

#ifndef ClassAH
#define ClassAH

...

#endif

因此,标题只会被包含一次......