2010-04-11 92 views
3
include/TestBullet.h:12: error: expected constructor, destructor, or type conver 
sion before '(' token 

我讨厌C++的错误消息...笑^^错误:预期的构造函数,析构函数或类型转换之前“(”令牌

基本上,我下面写着什么在this post尝试为项目符号创建一个工厂类,以便它们可以从一个字符串实例化,这个字符串将从一个xml文件中解析出来,因为我不想为所有类都有一个开关函数,因为这看起来很难看。

这里是我的TestBullet.h:

#pragma once 

#include "Bullet.h" 
#include "BulletFactory.h" 

class TestBullet : public Bullet { 
public: 
    void init(BulletData& bulletData); 
    void update(); 
}; 

REGISTER_BULLET(TestBullet); <-- line 12 

而且我BulletFactory.h:

#pragma once 

#include <string> 
#include <map> 
#include "Bullet.h" 

#define REGISTER_BULLET(NAME) BulletFactory::reg<NAME>(#NAME) 
#define REGISTER_BULLET_ALT(NAME, CLASS) BulletFactory::reg<CLASS>(NAME) 

template<typename T> Bullet * create() { return new T; } 

struct BulletFactory { 
    typedef std::map<std::string, Bullet*(*)()> bulletMapType; 
    static bulletMapType map; 

    static Bullet * createInstance(char* s) { 
     std::string str(s); 
     bulletMapType::iterator it = map.find(str); 
     if(it == map.end()) 
      return 0; 
     return it->second(); 
    } 

    template<typename T> 
    static void reg(std::string& s) { 
     map.insert(std::make_pair(s, &create<T>)); 
    } 
}; 

在此先感谢。

与错误无关,但有没有办法让Bullet包含BulletFactory而不会产生大量的错误(因为包含循环)?这样我就能从子弹的所有子类的顶部删除#include "BulletFactory.h"

+1

我很好奇是什么倒票。这是一个很好的问题。 – GManNickG 2010-04-11 21:04:56

回答

2

下面是你如何得到你想要的。 (不使用你的代码,准确,跳过包括标题,等只是为理念。):

// bullet_registry.hpp 
class bullet; 

struct bullet_registry 
{ 
    typedef bullet* (*bullet_factory)(void); 

    std::map<std::string, bullet_factory> mFactories; 
}; 

bullet_registry& get_global_registry(void); 

template <typename T> 
struct register_bullet 
{ 
    register_bullet(const std::string& pName) 
    { 
     get_global_registry().mFactories.insert(std::make_pair(pName, create)); 
    } 

    static bullet* create(void) 
    { 
     return new T(); 
    } 
}; 

#define REGISTER_BULLET(x) \ 
     namespace \ 
     { \ 
      register_bullet _bullet_register_##x(#x); \ 
     } 

// bullet_registry.cpp 
bullet_registry& get_global_registry(void) 
{ 
    // as long as this function is used to get 
    // a global instance of the registry, it's 
    // safe to use during static initialization 
    static bullet_registry result; 

    return result; // simple global variable with lazy initialization 
} 

// bullet.hpp 
struct my_bullet : bullet { }; 

// bullet.cpp 
REGISTER_BULLET(my_bullet) 

这是通过使一个全局变量,这将在静态初始化期间的某个时刻进行初始化。当发生这种情况时,在其构造函数中,它访问全局注册表并将其注册为名称以及用于创建项目符号的函数。

由于没有指定静态初始化顺序,因此我们将全局管理器放入一个函数中,所以当第一次按需要创建管理器并使用该函数时会调用该函数。这阻止了我们使用未初始化的管理器,如果它是一个简单的全局对象,情况可能如此。

免费免费要求澄清。

+0

谢谢。这真的很清楚 – jonathanasdf 2010-04-11 21:14:20

4

我不认为你可以调用函数以外的函数(只要你不使用结果初始化全局)。

+0

当我将呼叫转移到init函数时工作....谢谢 – jonathanasdf 2010-04-11 20:50:00

+1

@jon:你不想这样做。然后,您每次创建子弹的新实例时都会注册。 – GManNickG 2010-04-11 20:51:21

+0

啊是的。忘了那个..哪里会是最好的地方呢? – jonathanasdf 2010-04-11 20:54:21

2

reg()是一个函数。没有范围你不能调用一个函数。

相关问题