x6h*_*ius 2 c++ pointers c++11
到目前为止,我无法在Google上找到关于以下内容的解释,这让我感到困惑.
我有一个Scene存储层次结构SceneObjects.该Scene充当模板SceneObject厂,所以当簿记可以做到SceneObject创建或删除子类的实例.这两个类都在它们自己的动态链接模块中,并且位于模块命名空间内(不确定这是否重要).
(简化)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:
...
};
Run Code Online (Sandbox Code Playgroud)
而(简化)Scene类看起来像这样:
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;
}
...
};
Run Code Online (Sandbox Code Playgroud)
作为测试,我编译了以下代码来创建一个新的SceneObject:
ModuleNS::Scene scene;
ModuleNS::SceneObject* sceneObject =
scene.createSceneObject<ModuleNS::SceneObject>(NULL);
Run Code Online (Sandbox Code Playgroud)
但是,MSVC编译器给了我以下错误:
无法将参数2从'int'转换为'ModuleNS :: SceneObject*'
这让我很困惑,因为我认为NULL(即0)总是可以转换为指针类型.如果我使用static_cast<ModuleNS::SceneObject*>(NULL),或者nullptr(我想使用它,但为了与我一直使用的旧代码保持一致NULL),编译错误消失了.
具体是什么导致NULL停止可以转换为指针?
该错误与以下示例中的错误具有相同的性质
template <typename T> void foo(T t) {
void *p = t; // ERROR here
}
int main() {
foo(NULL);
}
Run Code Online (Sandbox Code Playgroud)
在C++中,只有文字0可以转换为指针类型以产生空指针值.NULL扩展到文字零,这就是为什么你可以用它来直接初始化/赋值/比较指针."直接"是这里的关键词.
但是一旦你通过函数参数提供它,它就不再是文字0,不能再作为空指针常量.
在上面的例子T中推导出一些整数类型.函数内部t只是一个碰巧有值的[run-time]整数0.并且不允许使用任意整数初始化指针.
请注意,在现代C++ NULL中实际上可以定义为nullptr,这将使上面的代码进行编译.但是,对于NULL(作为整体0)的"传统"定义,它不会.
| 归档时间: |
|
| 查看次数: |
734 次 |
| 最近记录: |