C++ 无法将NULL转换为指向对象类型的指针
到目前为止,我还无法在谷歌上找到以下内容的解释,这让我有点困惑 我有一个C++ 无法将NULL转换为指向对象类型的指针,c++,c++11,pointers,C++,C++11,Pointers,到目前为止,我还无法在谷歌上找到以下内容的解释,这让我有点困惑 我有一个场景,它存储场景对象的层次结构。场景充当模板化的场景对象工厂,以便在创建或删除场景对象子类实例时可以进行簿记。这两个类都位于自己的动态链接模块中,并且位于模块名称空间中(不确定这是否重要) (简化的)SceneObject类如下所示: // SceneObject is a base class, but is not pure. class SceneObject { // The parent Scene nee
场景
,它存储场景对象的层次结构
。场景
充当模板化的场景对象
工厂,以便在创建或删除场景对象
子类实例时可以进行簿记。这两个类都位于自己的动态链接模块中,并且位于模块名称空间中(不确定这是否重要)
(简化的)SceneObject
类如下所示:
// SceneObject is a base class, but is not pure.
class SceneObject
{
// The parent Scene needs to be able to access protected functions.
friend class Scene;
protected:
// This is protected to enforce the factory design pattern.
// We don't want SceneObjects created without being tied to a Scene.
SceneObject(Scene* parentScene, SceneObject* parentObject);
public:
...
};
class Scene
{
public:
// General bookkeeping - a fully constructed subclass is required
// here as the subclass constructor sets certain member variables.
void processSceneObjectCreated(SceneObject* object);
// This function means we can do:
// SceneObjectSub* obj = scene.createSceneObject<SceneObjectSub>(...)
// and pass whatever parameters are required for that particular
// subclass' constructor, while ensuring the Scene can keep a record
// of the created object.
//
// We can't call processSceneObjectCreated() in the SceneObject base
// class' constructor, as the required subclass constructor will not
// have been run yet.
template<typename T, typename... Args>
T* createSceneObject(Args... args)
{
T* obj = new T(this, std::move(args)...);
processSceneObjectCreated(obj);
return obj;
}
...
};
(简化的)场景
类如下所示:
// SceneObject is a base class, but is not pure.
class SceneObject
{
// The parent Scene needs to be able to access protected functions.
friend class Scene;
protected:
// This is protected to enforce the factory design pattern.
// We don't want SceneObjects created without being tied to a Scene.
SceneObject(Scene* parentScene, SceneObject* parentObject);
public:
...
};
class Scene
{
public:
// General bookkeeping - a fully constructed subclass is required
// here as the subclass constructor sets certain member variables.
void processSceneObjectCreated(SceneObject* object);
// This function means we can do:
// SceneObjectSub* obj = scene.createSceneObject<SceneObjectSub>(...)
// and pass whatever parameters are required for that particular
// subclass' constructor, while ensuring the Scene can keep a record
// of the created object.
//
// We can't call processSceneObjectCreated() in the SceneObject base
// class' constructor, as the required subclass constructor will not
// have been run yet.
template<typename T, typename... Args>
T* createSceneObject(Args... args)
{
T* obj = new T(this, std::move(args)...);
processSceneObjectCreated(obj);
return obj;
}
...
};
但是,MSVC编译器给了我以下错误:
无法将参数2从“int”转换为“ModuleNS::SceneObject*”
这让我很困惑,因为我认为NULL
(即0)总是可以转换为指针类型。如果我改为使用static_cast(NULL)
,或nullptr
(我很想使用它,但为了与我一直使用的NULL
旧代码保持一致),编译错误就会消失
是什么具体导致NULL不再可强制转换为指针?用C++的
nullptr
替换NULL
NULL扩展为的0值在通过
std::move
清洗时会“在翻译中丢失”,错误的性质与以下示例中的错误相同
template <typename T> void foo(T t) {
void *p = t; // ERROR here
}
int main() {
foo(NULL);
}
模板无效foo(T){
void*p=t;//此处有错误
}
int main(){
foo(空);
}
在C++中,只有文字>代码> 0代码>代码可以转换为指针类型,以生成空指针值。code>NULL扩展为文本零,这就是为什么可以使用它直接初始化/分配/比较指针。“直接”是这里的关键词
但是,一旦通过函数参数输入它,它就不再是文本0
,也不能再充当空指针常量
在上面的例子中,T
被推断为某种整数类型。函数中的t
只是一个[run-time]整数,正好有值0
。并且不允许使用任意整数初始化指针
注意,在现代C++ >代码> NUL>代码>中,实际上可以定义为代码> NulLPTR < /C>,这将使上述代码编译。但对于
NULL
(作为整数0
)的“传统”定义,它不会这样做。指针可以是64位。整数可以是32位?检查这里:我在64位系统上,所以这可能确实适用。我以前从未在项目中的任何其他代码中遇到过这个问题,所以我很好奇这段代码到底是什么导致了这个错误。你能不能再扩展一下“翻译中丢失”的意思?那么std::move
就是罪魁祸首?我不知道它会有那样的效果,但我想这是有道理的。我可能会回去重新编写代码,以一致地使用nullptr
。在这种情况下,可能值得付出努力。std::move
与此无关。该错误是由以下事实引起的:NULL
作为空指针常量的资格在通过函数参数列表后无法继续存在。我假设NULL
为0
的类型由模板系统推断为整数参数。将其类型设置为整数后,模板将生成一个int
参数。我想这就是它在翻译中丢失的地方。std::move
可能会导致这样的错误,因为它也是一个模板函数,所以std::move(NULL)
将返回一个int
而不是nullptr\t
。但是在代码示例中,即使删除了std::move
,您仍然会遇到AnT解释的问题。