如何在不知道具体类型的情况下引用变量?

时间:2013-12-07 15:42:23

标签: c++ openscenegraph

我对C ++很新,并且仍然试图了解模板/编写通用代码等中级概念的一些细节。我正在使用OpenSceneGraph(OSG)编写应用程序,基本上这就是我要做的事情:

  • 我希望有一个可以处理任意数量的不同元素'类型'的通用元素类
  • 一般元素类的每个实例应包含不同的形状(取决于类型)
  • 不同的元素类型(以及它们映射到的形状)只会在运行时被发现,因为它们将依赖于源数据 - 例如可以有6种不同的元素类型,它们都由不同大小的框表示。或者可以有3种不同的元素类型 - 一个Box,一个Cylinder,一个Cone。

有关OSG的一些背景信息,以解释我的问题的来源:

  • osg::Boxosg::Cylinder都属于osg::Shape
  • 两种派生类型都有相同的方法,getCenter
  • 即使您可以执行osg::Shape myShape = osg::Box();,也无法说myShape.getCenter(); - 对osg::Shape个对象不起作用。

以下是我正在尝试做的一个例子:

class MyClass {
private:
    // ???? How to reference 'shape' ??
public:
    MyClass(string _type) {
        // This is for example purposes. Eventually types & mappings will be discovered at run-time.

        if (_type == "FOO") { 
            shape = new osg::Box();
        } else if (_type == "BAR") {
            shape = new osg::Sphere();
        }
    }
    /* 
       ???? How to handle getShape()??
    */
}

int main() {
    string readFromData = "FOO";
    MyClass* myFoo (readFromData);

    string alsoFromData = "BAR";
    MyClass* myBar (alsoFromData);

    osg::Vec3f fooCenter = myFoo->getShape()->getCenter();
    osg::Vec3f barCenter = myBar->getShape()->getCenter();
}

我尝试了一些不同的方法,但还没有完全解决这个问题:

  • 创建扩展MyShape的{​​{1}}类,并且具有osg::Shape的虚函数头 - 但这会使getCenter成为无法实例化的抽象类。
  • MyShape - 但如果我们只发现类型&amp;在运行时形状映射,然后在我的其余代码中的尖括号中是什么?例如:template<typedef T> class MyClass...
  • 使用boost :: any在内部存储形状 - 但基本相同。如何定义一个MyClass<?????????>* myFoo;函数,它可以返回指向几种不同类型之一的指针?

我找不到任何以前专门针对此类情景的问题(抱歉,如果我错过了一个!)。如果有人能帮助我,那就太棒了!

2 个答案:

答案 0 :(得分:1)

OSG为此类情况提供osg::ShapeVisitor课程。创建一个扩展CenterFinderVisitor的{​​{1}}类,覆盖其每个虚拟成员函数以检索相应形状的中心。将osg::ShapeVisitor的实例传递给您在类中使用指针存储的形状实例上的CenterFinderVisitor osg::ShapeVisitor成员函数,以检索中心,如下所示:

accept()

现在,您可以按如下方式实施struct CenterFinderVisitor : public osg::ShapeVisitor { Vec3 center; virtual void apply (Sphere &s) { center = s.getCenter(); } virtual void apply (Box &b){ center = b.getCenter(); } // ...and so on for other shapes }; 方法:

getCenter()

如果您不熟悉访客模式read this article on wikipedia

答案 1 :(得分:0)

这是一个经典的OOP问题。

拥有shape基类并使所有形状都从中继承。 在形状中声明您希望形状具有的所有函数(纯虚拟或仅虚拟):

class shape {
public:
   shape(string _name) : name(_name) {}
   virtual ~shape(); // virtual desructor
   virtual POINT getCenter() = NULL;
   virtual getName() { return name; } // example - functionality in base class

protected:
   string name;
};

class rectangle : public shape {
{
   rectangle() : shape("rectangle") {}
   virtual POINT getCenter() { return /* do math here :) */ }
};

在MyClass类中,指针/ ref为shape类型。