From: JSeb on

> Requiring the programmer to provide a full definition gives you full
> control on the specialization, in the sense that not only you can add or
> replace features, you can also remove them.

But what if I want to reuse them?

Suppose CTemplateClass<T> contains a gazillion methods; will I have to
redeclare/redefine them all in CTemplateClass<T*> ?

From my current understanding, the answer would be yes: even if
CTemplateClass<T>::FooBar() and CTemplateClass<T*>::FooBar() are
identical, FooBar has to be defined in both class templates...

Wouldn't there be another way, that wouldn't require me to maintain a
class template and its specialization "in sync"? Should I look towards
class template INHERITANCE?

Thank you so much for your answer!

> PS: exercise for the reader: give the OP's definitions, what is the
> destructor of CTemplateClass<T*>?

CTemplateClass<T>::~CTemplateClass()
{
delete this->mpData;
}
CTemplateClass<T*>::~CTemplateClass()
{
// Show some manners!
//delete this->mpData;
}

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: JSeb on
Okay: here's what I came up with, after your much appreciated
comments. Instead of a helper class, I'm trying to use a common base
class for the main template, and its specialization.

Any comment will be much appreciated!

Thanks again.

==========================

// *** COMMON BASE CLASS ***
template <typename T>
class ATemplateClassCommonInterface
{
protected:
const T* const mpData;
int mCounter;
protected:
ATemplateClassCommonInterface(const T* apData, int aCounter = 0) :
mpData(apData), mCounter(aCounter) { }
public:
virtual ~ATemplateClassCommonInterface() { }
// COMMON INTERFACE --- TO BE IMPLEMENTED IN DERIVED TEMPLATES
virtual void specializedMethod() = 0;
// COMMON INTERFACE --- IMPLEMENTED HERE
void commonMethod()
{
std::cout << "commonMethod : mCounter = " << this->mCounter <<
std::endl;
this->mCounter++;
}
};

// *** MAIN CLASS TEMPLATE ***
template <typename T>
class CTemplateClass : public ATemplateClassCommonInterface<T>
{
public:
CTemplateClass(const T& aData) :
ATemplateClassCommonInterface<T>(new T(aData), 0)
{
std::cout << "CTemplateClass<T>::CTemplateClass : *mpData = "
<<
*(this->mpData) << std::endl;
}
virtual ~CTemplateClass()
{
delete this->mpData;
}
void specializedMethod()
{
std::cout << "CTemplateClass<T>::specializedMethod" <<
std::endl;
}
};

// *** SPECIALIZED CLASS TEMPLATE ***
template <typename T>
class CTemplateClass<T*> : public ATemplateClassCommonInterface<T>
{
public:
CTemplateClass(const T* apData) :
ATemplateClassCommonInterface<T>(apData, 10)
{
std::cout << "CTemplateClass<T*>::CTemplateClass : *mpData = "
<<
*(this->mpData) << std::endl;
}
virtual ~CTemplateClass()
{
// Show some manners.
//delete this->mpData;
}
void specializedMethod()
{
//AHelper_TemplateClass<T>::specializedMethod(this);
std::cout << "CTemplateClass<T*>::specializedMethod" <<
std::endl;
}
};

==========================

In the Main function,
CTemplateClass<int>* pTC1 = new CTemplateClass<int>(10);
CTemplateClass<int*>* pTC2 = new CTemplateClass<int*>(new int(15));
pTC1->commonMethod();
pTC2->commonMethod();
pTC1->specializedMethod();
pTC2->specializedMethod();
delete pTC1;
delete pTC2;

Output:
CTemplateClass<T>::CTemplateClass : *mpData = 10
CTemplateClass<T*>::CTemplateClass : *mpData = 15
commonMethod : mCounter = 0
commonMethod : mCounter = 10
CTemplateClass<T>::specializedMethod
CTemplateClass<T*>::specializedMethod


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Alberto Ganesh Barbati on
JSeb ha scritto:
>> Requiring the programmer to provide a full definition gives you full
>> control on the specialization, in the sense that not only you can add or
>> replace features, you can also remove them.
>
> But what if I want to reuse them?
>
> Suppose CTemplateClass<T> contains a gazillion methods; will I have to
> redeclare/redefine them all in CTemplateClass<T*> ?

Yes.

> From my current understanding, the answer would be yes: even if
> CTemplateClass<T>::FooBar() and CTemplateClass<T*>::FooBar() are
> identical, FooBar has to be defined in both class templates...

Correct.

> Wouldn't there be another way, that wouldn't require me to maintain a
> class template and its specialization "in sync"? Should I look towards
> class template INHERITANCE?
>

If you want to factor code common to all specializations, you can use a
base class, for example:

template <class T>
class CTemplateClassCommon
{ /* common part */ };

template <class T>
class CTemplateClass : public CTemplateClassCommon<T>
{ /* main template */ };

template <class T>
class CTemplateClass<T*> : public CTemplateClassCommon<T*>
{ /* specialization */ };

>
>> PS: exercise for the reader: give the OP's definitions, what is the
>> destructor of CTemplateClass<T*>?
>
> CTemplateClass<T>::~CTemplateClass()
> {
> delete this->mpData;
> }
> CTemplateClass<T*>::~CTemplateClass()
> {
> // Show some manners!
> //delete this->mpData;
> }
>

Gotcha! The right answer is that, given the OP's definition, the
destructor of CTemplateClass<T*> is trivial. That's because you didn't
declare it (the declaration in CTemplateClass<T> doesn't count!) and the
class has neither bases nor data members.

It's illegal to explicitly provide an implementation of a trivial
destructor, as the compiler implicitly generates it for you. Notice, in
particular, that while the destructor of CTemplateClass<T> is virtual,
the destructor of CTemplateClass<T*> isn't. Because of that,
CTemplateClass<T> is polymorphic and CTemplateClass<T*> isn't.

HTH,

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  | 
Pages: 1 2
Prev: Explicit casts to user-defined types
Next: Composition