cannot declare variable ‘’ to be of abstract type ‘’
Asked Answered
D

2

22

EDIT: After spending a bit of time understanding the code I wrote I still don't know what is wrong with it. This is the base class from which I derived my class:

///ContactResultCallback is used to report contact points
struct  ContactResultCallback
{
    short int   m_collisionFilterGroup;
    short int   m_collisionFilterMask;

    ContactResultCallback()
        :m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
        m_collisionFilterMask(btBroadphaseProxy::AllFilter)
    {
    }

    virtual ~ContactResultCallback()
    {
    }

    virtual bool needsCollision(btBroadphaseProxy* proxy0) const
    {
        bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
        collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
        return collides;
    }

    virtual btScalar    addSingleResult(btManifoldPoint& cp,    const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) = 0;
};

Now here is my derived class:

class DisablePairCollision : public btCollisionWorld::ContactResultCallback
{
public:
    virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0, int32_t partId0, int32_t index0, const btCollisionObject* colObj1, int32_t partId1, int32_t index1);

    btDiscreteDynamicsWorld* DynamicsWorld;
};

And below is where I implement the main function. Still not sure why I'm getting this error.

I was using the code below on windows with both vc2010 and code blocks without a problem:

btScalar DisablePairCollision::addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0, int32_t partId0, int32_t index0, const btCollisionObject* colObj1, int32_t partId1, int32_t index1)
{
    // Create an identity matrix.
    btTransform frame;
    frame.setIdentity();

    // Create a constraint between the two bone shapes which are contacting each other.
    btGeneric6DofConstraint* Constraint;
    Constraint = new btGeneric6DofConstraint( *(btRigidBody*)colObj0, *(btRigidBody*)colObj1, frame, frame, true );

    // Set limits to be limitless.
    Constraint->setLinearLowerLimit( btVector3(1, 1, 1 ) );
    Constraint->setLinearUpperLimit( btVector3(0, 0, 0 ) );
    Constraint->setAngularLowerLimit( btVector3(1, 1, 1 ) );
    Constraint->setAngularUpperLimit( btVector3(0, 0, 0 ) );

    // Add constraint to scene.
    DynamicsWorld->addConstraint(Constraint, true);
    return 0;
}

Now I'm trying to compile my project on Ubuntu but I am getting this error when I try to use that class:

/home/steven/Desktop/ovgl/src/OvglScene.cpp:211: error: cannot declare variable ‘Callback’ to be of abstract type ‘Ovgl::DisablePairCollision’
Decorate answered 25/7, 2012 at 0:5 Comment(4)
@LuchianGrigore: better: Where's Callback?Laborsaving
@SteveDeFacto: what compiler are you using with Code::Blocks on Windows?Laborsaving
Callback is a variable inside a class function. I define it like this: DisablePairCollision Callback; I used GCC MinGW compiler in code blocks.Decorate
@SteveDeFacto: The code you posted has nothing to do with the error. Why did you post it? And why didn't you post the code that contains the actual error line?Lobule
U
41

The reason the base class is abstract is this pure virtual function:

virtual btScalar addSingleResult(
  btManifoldPoint& cp,
  const btCollisionObjectWrapper* colObj0Wrap,
  int partId0,
  int index0,
  const btCollisionObjectWrapper* colObj1Wrap,
  int partId1,
  int index1) = 0;

The derived class DisablePairCollision attempts to define that function, but it does not do it correctly:

virtual btScalar addSingleResult(
   btManifoldPoint& cp,
   const btCollisionObject* colObj0,
   int32_t partId0,
   int32_t index0,
   const btCollisionObject* colObj1,
   int32_t partId1,
   int32_t index1);

As you can see, some of the arguments have different types. E.g. colObj0 is of type const btCollisionObject*, but it should be of type const btCollisionObjectWrapper*.

Therefore, the derived class defines a new function with different arguments, but it does not define the pure virtual function from the base class, hence the derived class is still abstract.

You need to define the function with the exact same argument types as in the base class.

Underhand answered 25/7, 2012 at 1:41 Comment(2)
Apparently I must have a different version of bullet installed. Thank you!Decorate
The use of the override keyword can help avoiding this kind of trap by generating a compilation error if the virtual fonction does not exactly redefine the same function : virtual btScalar addSingleResult() override; if the fonction is not exactly the same, the compilation error is quite explicit and would look like : marked ‘override’, but does not overridePrognathous
K
9

Ovgl::DisablePairCollision is an abstract class, meaning it contains at least one pure virtual function.

You need to derive from this class and implement the abstract functionality of it.

For example:

class DisablePairCollision { virtual void foo() = 0; };
class DerivedClass : public DisablePairCollision { virtual void foo() {} };

DisablePairCollision* pCallback;
pCallback = new DerivedClass;
pCallback->foo(); 
Koodoo answered 25/7, 2012 at 0:35 Comment(1)
There was a time when I understood that code but now I have no idea how it works. Where I post the code above is actually how that function/class thing was defined. Urg...Decorate

© 2022 - 2024 — McMap. All rights reserved.