2010-09-17 59 views
3

我有兩個類(ClassA和ClassB),他們都有兩種方法(比較和收斂)。這些方法的工作方式完全相同,但這些類不是多態關聯的(出於很好的原因)。我想定義一個函數模板,這兩個類都可以顯式實例化爲一個成員,但我得到錯誤,因爲這些方法使用「this」,當我將它們變成模板時,編譯器會拋出錯誤,因爲它們不是成員函數。C++實例化函數模板作爲類成員並使用「this」指針

因爲這個限制,這是不可能的嗎?還是有一些方法可以在沒有聲明爲模板類的一部分的函數模板中使用「this」。我做了一些研究,沒有發現任何東西。

Logic.h

template <class T> 
T* compare(const T& t) { 
//stuff involving this 
} 

template <class T> 
T* converge(const T& t,bool b) { 
//other stuff involving this 
} 

ClassA.cpp

#include "ClassA.h" 
#include "Logic.h" 
//constructors 

template ClassA* ClassA::compare(const ClassA& t) const; 
template ClassA* ClassA::converge(const ClassA& t,bool b) const; 
//other methods 

CLASSB是相似的。

任何幫助表示讚賞!

+0

它是_「函數模板」_,而不是「模板函數」,因爲這些東西不是函數,而是可以實例化哪些函數的_templates_。 – sbi 2010-09-17 08:41:19

+0

「這些類不是多態相關的(出於很好的理由)。」 - 聽起來很像他們應該有一個共同的基礎,如果有可能寫一個兼容的成員函數。請注意,繼承並不意味着多態(如私有繼承)。 – Potatoswatter 2010-09-17 08:49:54

回答

2

我相信你可以在這裏使用CRTP。下面是一個例子,你可以省略friend聲明的情況下,你可以做的比較僅使用公共成員:

template<class T> 
class comparer 
{ 
public: 
    T* compare(const T& t) 
    { 
     //Use this pointer 
     bool b = static_cast<T*>(this)->m_b == t.m_b; 
     return NULL; 
    } 
}; 

class A : public comparer<A> 
{ 
public: 
    friend class comparer<A>; 
    A() : m_b(0) 
    { 
    } 

private: 
    int m_b; 
}; 

class B : public comparer<B> 
{ 
public: 
    friend class comparer<B>; 
    B() : m_b(0) 
    { 
    } 

private: 
    int m_b; 
}; 

int main() 
{ 
    A a1,a2; 
    A* p = a1.compare(a2); 

    B b1,b2; 
    B* p1 = b1.compare(b2); 

    return 0; 
} 
+0

給'comparer'一個受保護的非虛擬析構函數是有用的。 – 2010-09-17 12:44:59

0

不能使用這裏面的非成員函數。你可以做的是創建模板函數並將它聲明爲你的classA和classB的一個朋友。但通過模板函數訪問的classA和classB成員必須具有相同的名稱。

template <typename T> 
bool compare(const T& t1, const T& t2) 
{ 
    return t1.val == t2.val; 
} 

class A 
{ 
public: 
    template <typename T> 
    friend bool compare(const T&, const T&); 

    bool compare(const A& a) 
    { 
     return ::compare(*this, a); 
    } 

private: 
    int val; 
}; 

A a1, a2; 
a1.compare(a2); 
0

你想要什麼是不可能的。成員函數必須聲明並定義爲成員。成員函數模板也是如此,從中可以實例化成員函數。

但是(爲什麼)這些功能必須是成員?如果這些函數不需要訪問這些類中的私有內容,請將它們設爲自由函數模板。整個STL(其中,BTW僅僅是C++標準庫的一部分)是圍繞非成員函數構建的,並且實現了更高級別的抽象,因爲任何面向前的OO容器庫都會實現。
與普遍相信,non-member functions generally increase encapsulation

如果你正在編寫,可以實現爲成員或作爲非朋友非成員函數,你應該更喜歡來實現它作爲一個非成員函數。該決定增加了類封裝。當你認爲封裝時,你應該考慮非成員函數。