2010-09-17 2 views
3

У меня есть два класса (ClassA и ClassB), у которых есть два метода (сравнение и схождение). Эти методы работают точно так же, но эти классы не связаны полиморфно (по уважительной причине). Я хотел бы определить шаблон функции, который оба эти класса могут явным образом создавать экземпляр как член, но я получаю ошибки, потому что методы используют «это», и когда я превращаю их в шаблон, компилятор выдает ошибку, потому что они не являются функции-члены.C++ экземпляр шаблона функции как член класса и с помощью этого «указателя»

Возможно ли это из-за этого ограничения? Или есть способ использовать «это» внутри шаблона функции, который не объявлен как часть класса шаблона. Я провел некоторое исследование и ничего не нашел.

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

+0

"эти классы не связаны полиморфно (по уважительной причине)". - это очень похоже на то, что у них должна быть общая база, если можно написать функцию-член, совместимую с любым из них. Обратите внимание, что наследование не подразумевает полиморфизм (например, личное наследование). – Potatoswatter

ответ

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' защищенный не виртуальный деструктор. –

0

Вы не можете использовать эту функцию внутри, не являющиеся членами. Что вы можете сделать, так это создать функцию шаблона и объявить ее как друга вашего класса A и 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:

Если вы пишете функцию, которая может быть реализована в виде либо члена или как не друг, не являющегося членом, вы должны предпочесть реализовать его как не- член функция. Это решение увеличивает инкапсуляцию класса. Когда вы думаете об инкапсуляции, вы должны думать о нечленовских функциях.

 Смежные вопросы

  • Нет связанных вопросов^_^