如何在C ++中为多个对象类型使用void *参数?

时间:2013-05-22 20:28:52

标签: c++ void void-pointers

简而言之,我创建了多个类来表示来自不同设备(实际上是摄像头)的数据。它们在引擎盖下都有不同的行为,但是交互的构建与外部完全相同。我正在尝试编写一个实用程序函数,可以使用任何一个类,或者可能是我编写的任何类,只要交互是相同的。我对C ++很陌生,所以如果我的术语不完全正确,请耐心等待。

所以我想说我对每个摄像机都有这些定义。

class CamDataA
{
int getImageStart() {return ptrToStart;)
    int getImageSize() {return imageSizeVariable;)
}; 

class CamDataB
{
int getImageStart() {return ptrToStart;)
    int getImageSize() {return width*height*channels;)
}; 

我希望有另一个单独的类可以与任何一个类

互换
class imageUtils
{
    //constructors/destructors

    int reportSize( void* camData)
    {
        cout << camData->getImageSize();
    }

}; 

但编译时遇到的错误是:

error: ‘void*’ is not a pointer-to-object type

这甚至可能吗?

2 个答案:

答案 0 :(得分:5)

void *是一个无类型指针。要通过指针调用对象的方法,指针必须是适当的类型。如果您知道它所指向的对象,您可以明确地将void *投射到CamDataA*CamDataB*,但这不是您想要的(您事先不知道对象的类型)

在您的情况下,使用虚拟方法很好。

1)定义界面。即定义一组没有实现的方法。

class CamDataBase {
  public:
    virtual int getImageStart() = 0;  // "=0" means abstract methods - MUST be 
    virtual int getImageSize() = 0;   // overriden in descendants
};

关键字virtual表示该方法可以在后代类中进行重写。这意味着如果我们有一个指针,比如CamDataBase* p,并且指针指向一些后代类,例如p = new CamDataA(),如果我们写p->getImageStart(),那么将会调用对应真实(当前)类型的对象(CamDataA::getImageStart())的方法,而不是CamDataBase::getImageStart(),尽管{ {1}}是指向p的指针。

2)现在定义接口的几个实现。与父类中的虚拟方法具有相同签名的方法覆盖它们。

CamDataBase

3)现在定义一个接受指向class CamDataA: public CamDataBase { int getImageStart() {return ptrToStart;) int getImageSize() {return imageSizeVariable;) }; class CamDataB: public CamDataBase { int getImageStart() {return ptrToStart;) int getImageSize() {return width*height*channels;) }; 或其任何后代的指针的函数:

CamDataBase

以下是几个例子:

void reportSize(CamDataBase* camData) // using the base class
{
   // type of the object and the appropriate method 
   // are determined at run-time because getImageSize() is virtual
   std::cout << camData->getImageSize();
}

我希望你能在网上搜索所有新词。 :)

答案 1 :(得分:1)

似乎第二个函数是小写,而你将它作为大写,并且没有将它强制转换为特定对象。 ((CamDataA *)camData) - &GT;和getimagesize ...

然而,这不是用C ++做的方法,我建议你多阅读一些关于面向对象的内容......因为做演员和使用void *是非常类似C语法。

使用面向对象,您可以进行类型检查(因为您可以将任何内容传递给void *),它们为您的程序提供了更多的结构和清晰度。 C ++(以及其他面向对象的语言)使用Base类作为契约,它表示此类型的所有对象都应该具有这些函数(方法),因此例如bag的基类定义了PutItemInBag的方法,然后是背包,手提箱,手提包等等都从bag继承而且每个都可以有不同的PutItemInBag实现并以不同的方式处理它,因为这种方式外部对象可以处理所有的包相同而不必担心它是哪个对象,或者是否有新类型的对象系统。 这是通过虚拟方法完成的 - Virtual Method Overview

然后,您可以通过使用抽象虚拟方法使基类抽象化 (在C ++中使其= 0)。这意味着此方法没有实现,您无法创建此类型的对象。此类只是一个接口(或契约),从它继承的方法应该重写此方法并提供自己的实现。 Abstract Classes

你需要的是让两个类都有一个抽象的基类并以这种方式处理它。

class BaseCamData
{
  virtual int getImageSize() = 0;
};

//then have both class inherit form it.
class CamDataA : public BaseCamData
{
  virtual int getImageSize () {return 50;/*imagesize*/}
}

class CamDataB : public BaseCamData
{
  virtual int getImageSize () {return 70;/*imagesize*/}
}




int reportSize(BaseCamData* camData)
{
     count << camData->getImageSize();
}

}