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

C++ 如何在C+;中使用void*参数+;对于多个对象类型?,c++,void,void-pointers,C++,Void,Void Pointers,简而言之,我创建了多个类来表示来自不同设备(实际上是照相机)的数据。它们在引擎盖下都有不同的行为,但从外部来看,相互作用是完全相同的。我正在尝试编写一个实用函数,它可以与任何一个类一起工作,也可以与我编写的任何其他类一起工作,只要交互是相同的。我对C++很陌生,所以如果我的术语不完全正确,请耐心等待。 假设我对每台相机都有这些定义 class CamDataA { int getImageStart() {return ptrToStart;) int getImageSize() {r

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

}; 

这可能吗

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

<>但是,C++不是这样做的,我建议你多读一些关于面向对象的……因为做CAST和使用空隙*是非常类似于C的语法。 使用面向对象,您可以进行类型检查(因为您可以将任何内容传递给void*),它们为您的程序提供了更多的结构和清晰度。 C++(和其他面向对象的语言)使用基类作为契约,表示这种类型的所有对象都应该具有这些函数(方法),例如,包的基类定义了PATTIMIN包的方法,然后是背包、手提箱、手提包,etc都继承自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();
}
classbasecamdata
{
虚拟int getImageSize()=0;
};
//然后让这两个类从中继承。
CamDataA类:公共基础CAMData
{
虚拟int getImageSize(){return 50;/*imagesize*/}
}
CAMDATA类:公共基础CAMDATA
{
虚拟int getImageSize(){return 70;/*imagesize*/}
}
int reportSize(BaseCamData*camData)
{
计数getImageSize();
}

}
void*
是一个非类型指针。要通过指针调用对象的方法,指针必须是适当的类型。如果您知道它指向的对象,但这不是您想要的(您事先不知道对象的类型),则可以将
void*
显式强制转换为
CamDataA*
camdata*

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

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) 现在定义接口的两个实现。与父类中的虚拟方法具有相同签名的方法将重写它们

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

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

你的答案是正确的,但我建议你编辑它,并向他解释你做了什么以及为什么..我认为他不理解OO,这是他在这里遇到的最大问题:)同意,我可以遵循代码,但仍然不知道你具体做了什么以及为什么。谢谢谢谢,我将编辑答案。我只是希望“虚拟”和“覆盖”这两个词能引导他开始学习面向对象编程:)我不确定这里是否是一个合适的地方来详细介绍多态性这样一个描述良好的主题。
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;)
}; 
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