2009-09-17 66 views
1

對於用於識別我實例一些跟蹤自動化想調用任一:在編譯時區分C++中的靜態和非靜態方法?

  • 包含對象的非靜態方法返回它的識別符
  • 別的它總是返回相同的id

我目前的解決方案是有一個基類,其中有一個方法()和一個全局函數which(),如果不是在一個對象的上下文中應該使用它。 但是這對於靜態成員函數不起作用,在這裏編譯器更喜歡全局函數的非靜態方法。

簡單的例子:

class IdentBase 
{ 
public: 
    Ident(const std::string& id) _id(id) {} 
    const std::string& which() const { return _id; } 
private: 
    const std::string _id; 
}; 

const std::string& which() { static const std::string s("bar"); return s; } 

#define ident() std::cout << which() << std::endl 

class Identifiable : public IdentBase 
{ 
public: 
    Identifiable() : Ident("foo") {} 
    void works() { ident(); } 
    static void doesnt_work() { ident(); } // problem here 
}; 

我可以以某種方式避免使用變通像靜態成員函數(可能使用一些模板魔術)一個特殊的宏?

+1

我敢肯定,有一種方法可以通過使用函數指針並使用成員函數大小寫的一些聯編程序來實現。但首先我會質疑設計。爲什麼你認爲你需要在靜態和非靜態可識別成員函數中編寫相同的代碼?像往常一樣,「我怎樣才能解決這個問題?」可能比「我被困在這條路上解決我的問題困難得多,我該如何更進一步?」 – sbi

+0

我想使用相同的代碼,因爲我想簡單地使用一箇中央宏而不是一個用於靜態而一個用於非靜態上下文。 也許設計是不對的,但至少我自己看不到更好的設計。 –

回答

0

您可能能夠使用Boost TypeTraits庫中的 is_member_function_pointer。 sbi在靜態和非靜態情況下使用不同代碼的建議可能會更好。

+0

快速測試看起來不錯,謝謝。 –

0

您是否需要爲每個類的每個實例使用不同的標識符(如您的示例中所示),還是隻是試圖確定跟蹤中的哪個類?

將您的哪個()函數和_id成員更改爲靜態會將它們暴露給您的靜態成員函數,並作爲獎勵減少您的內存使用量。

+0

是的,我這樣做是爲了識別同一班級及其孩子的不同實例。 –

+0

在這種情況下,什麼是靜態方法,爲什麼它必須具有相同的主體?否則,你可以a)通過ident宏(或函數)打印什麼(this-> which()或:: which()),或者你可以實現靜態的:{using :: which; IDENT(); } – UncleBens

+0

我的目標是根據上下文使用大部分「自動」跟蹤/日誌宏的集合,而不是任何特定的集合。這些應該儘可能自動記錄它們所屬的主要實例。 {using :: which(); ...}會違背簡單和自動化的目標,就像傳遞明確的信息一樣。 叫我懶,但我不想考慮在哪種情況下,如果我能以某種方式自動化。 –

1

定義一個返回所有類型的默認標識符的函數模板。

template<typename T> 
const std::string& which(const T& object) 
{ static const std::string s("bar"); return s; } 

專門針對特定類的函數模板。

class IdentBase 
{ 
public: 
    IdentBase(const std::string& id): _id(id) {} 
    const std::string& id() const { return _id; } 
private: 
    const std::string _id; 
}; 

template<> 
const std::string& which(const IdentBase& object) 
{ return object.id(); } 

通過傳遞要識別的實例來調用函數模板。

int main() 
{ 
    int i; 
    std::cout << which(i) << std::endl; 

    IdentBase foo("foo"); 
    std::cout << which(foo) << std::endl; 

    return 0; 
} 
+0

對不起,但我沒有看到哪裏可以讓我調用哪個()在一箇中央宏沒有不同的代碼靜態/非靜態上下文。 –

+0

對不起,我沒有注意到你需要一個無參數宏來標識實例。我的解決方案要求您傳遞實例作爲參數。 –