我试图创建一个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
Aaditi:
继承人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()
{
}
};
createInstance定义:
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;
}
//...
}
好像我发现了错误:PhysX SDK中的大多数析构函数都不公开。因此,尝试使用这些类之一创建智能指针会导致错误。除了使用原始指针之外,只有其他选项是创建自定义删除器:
auto foundation = std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback), [=](physx::PxFoundation* f)
{
f->release();
});
你的foundation =
行实际上并没有调用构造函数。它试图使用名为“functional cast”或“function-style cast”(#2 shared_ptr
)的语法将原始指针强制转换为here,然后将结果分配给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));
}