2

简而言之,我创建了多个类来表示来自不同设备(实际上是相机)的数据。它们在幕后都有不同的行为,但从外部看,它们的交互是完全相同的。我正在尝试编写一个可以与任一类或我编写的任何其他类一起使用的实用程序函数,只要交互是相同的。我对 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

这甚至可能吗?

4

2 回答 2

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(),虽然p是指向 的指针CamDataBase

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

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;)
}; 

3) 现在定义一个函数,该函数接受一个指向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();
}

这里有几个例子:

CamDataA A;
CamDataB B;
reportSize(&A); // CamDataA::getImageSize() is called
reportSize(&B); // CamDataB::getImageSize() is called

CamDataBase *p = &A;
reportSize(p); // CamDataA::getImageSize() is called

// and even if we cast pointer to CamDataA* to a pointer to CamDataB*:
reportSize((CamDataB*)&A); // CamDataA::getImageSize() is called

我希望你能在网上搜索所有对你来说陌生的词。:)

于 2013-05-22T20:36:53.187 回答
1

似乎第二个函数是小写的,而您将其定义为大写,并且您没有将其转换为特定对象。(((CamDataA*)camData)->getImageSize...

但是,这不是在 C++ 中执行此操作的方法,我建议您阅读更多有关面向对象的内容...因为进行强制转换和使用 void* 非常类似于 C 语法。

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

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

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

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();
}

}

于 2013-05-22T20:31:41.557 回答