0

我试图创建一个 PxFoundation 并将其保存在我的成员变量“foundation”中,它是一个 std::shared_ptr。然而,在创建对象时,我得到了这个:

C2440: '<function-style-cast>': cannot convert from 'physx::PxFoundation *' to 'std::shared_ptr<physx::PxFoundation>'

如何将 PxCreateFoundation 函数中的原始指针放入 shared_ptr?因为我没有调用任何 PhysX 类的 ctor,所以我不能使用 std::make_shared,所以使用普通的 std::shared_ptr<>() 构造函数似乎是我唯一的选择?

代码:

#include <memory>
#include <PxPhysics.h>
#include "PhysXErrorCallback.hpp"
#include "PhysXDefaultAllocator.hpp"
#include <foundation/PxFoundationVersion.h>

class PhysicsEngine
{
public:


    PhysicsEngine();

    std::shared_ptr<physx::PxFoundation> foundation;

    static PhysXErrorCallback gDefaultErrorCallback;
    static PhysXDefaultAllocator gDefaultAllocatorCallback;
};

PhysicsEngine::PhysicsEngine()
{
    foundation =  std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback));
}

编辑: 改变后

foundation = std::shared_ptr<physx::PxFoundation>(...) 

foundation.reset(...)

它现在给了我这些错误:

1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1519): error C2440: '<function-style-cast>': cannot convert from 'physx::PxFoundation *' to 'std::shared_ptr<physx::PxFoundation>'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1519): note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>physicsengine.cpp(25): note: see reference to function template instantiation 'void std::shared_ptr<physx::PxFoundation>::reset<physx::PxFoundation>(_Ux *)' being compiled
1>        with
1>        [
1>            _Ux=physx::PxFoundation
1>        ]
1>physicsengine.cpp(25): note: see reference to function template instantiation 'void std::shared_ptr<physx::PxFoundation>::reset<physx::PxFoundation>(_Ux *)' being compiled
1>        with
1>        [
1>            _Ux=physx::PxFoundation
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1519): error C2228: left of '.swap' must have class/struct/union

编辑2:

下面是 PxCreateFoundation 声明和定义:

PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation* PX_CALL_CONV
PxCreateFoundation(physx::PxU32 version, physx::PxAllocatorCallback& allocator, physx::PxErrorCallback& errorCallback);

physx::PxFoundation* PxCreateFoundation(physx::PxU32 version, physx::PxAllocatorCallback& allocator,
                                    physx::PxErrorCallback& errorCallback)
{
    return physx::shdfnd::Foundation::createInstance(version, errorCallback, allocator);
}

PxFoundation 类:

/**
\brief Foundation SDK singleton class.

You need to have an instance of this class to instance the higher level SDKs.
*/
class PX_FOUNDATION_API PxFoundation
{
  public:
    virtual void release() = 0;

  protected:
    virtual ~PxFoundation()
    {
    }
};

创建实例定义:

Foundation* Foundation::createInstance(PxU32 version, PxErrorCallback& errc, PxAllocatorCallback& alloc)
{
//...
    mInstance = reinterpret_cast<Foundation*>(alloc.allocate(sizeof(Foundation), "Foundation", __FILE__, __LINE__));

    if(mInstance)
    {
        PX_PLACEMENT_NEW(mInstance, Foundation)(errc, alloc);
        return mInstance;
    }
//...
}
4

2 回答 2

2

好像我发现了错误:PhysX SDK 中的大多数析构函数都是不公开的。因此,尝试使用这些类之一创建智能指针会导致错误。除了使用原始指针之外,唯一的其他选择是创建自定义删除器:

auto foundation = std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback), [=](physx::PxFoundation* f)
{
    f->release();
});
于 2018-03-03T05:16:03.690 回答
-1

您的foundation =行实际上并没有调用构造函数。它尝试shared_ptr使用称为“函数式转换”或“函数式转换”(此处为#2 )的语法将原始指针转换为 a,然后将结果分配给foundation变量(已默认构造)。这是行不通的,因为shared_ptr没有来自原始指针的强制转换(以防止它意外地获得它不应该拥有的东西的所有权)。

解决问题的最佳方法是使用构造函数的初始化器列表来实际foundation使用指针进行初始化:

PhysicsEngine::PhysicsEngine() :
foundation(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback))
{
  // empty
}

这会将指针传递给foundation的构造函数,而不是让其foundation默认构造,然后在构造函数主体中分配给它。但是,如果您出于某种原因确实需要通过赋值来完成,您可以使用该reset函数来告诉foundation获取指针的所有权:

PhysicsEngine::PhysicsEngine()
{
    foundation.reset(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback));
}
于 2018-02-28T07:50:22.507 回答