2010-04-11 94 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()是一個函數。沒有範圍你不能調用一個函數。

相關問題