I try to program a smart-pointer using policies. I rely heavyly on templates
during this. The program compiles fine - but I get a linker error:
test.o(.text+0x 3e): In function `testSmartPtr() ':
/home/tobias/project/Heart/heartofoak/test.cpp:23: undefined reference to
`SmartPtr<LongW rapper, RefCount>::Smar tPtr[in-charge](LongWrapper*)'
collect2: ld returned 1 exit status
I think the linker does not find the Constructor of the
SmartPointer<Lo ngWrapper, RefCount>.
The Code:
template <class T, template <class> class OwnershipPolicy >
class SmartPtr : public OwnershipPolicy <T> {
public:
explicit SmartPtr(T* pointer);
SmartPtr(const SmartPtr<T, OwnershipPolicy >& otherPointer);
SmartPtr& operator=(const SmartPtr<T, OwnershipPolicy >& otherSmartPtr);
~SmartPtr();
T& operator*() const;
T* operator->() const;
private:
void copyPtr(const SmartPtr<T, OwnershipPolicy >& otherPointer);
SmartPtr();
T* pointer_;
};
/* Policy Klassen fuer Kopien */
template <class T>
class RefCount {
private:
long *count_;
void initOwnership() ;
bool dispose();
bool copy(const SmartPtr<T, RefCount<T> >&);
friend class SmartPtr<T, RefCount>;
};
#include "smartptr.h "
#define DEBUG 1
#ifdef DEBUG
#include <iostream>
#endif
// not allowed, thus declared private and not implemented
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >::SmartPtr() {
}
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >::SmartPtr(T * pointer): pointer_(pointe r) {
#ifdef DEBUG
std::cout << "SmartPtr Constructor\n";
#endif
initOwnership() ;
}
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >::~SmartPtr( ){
#ifdef DEBUG
std::cout << "SmartPtr Destructor\n";
#endif
if (dispose() && pointer_!=NULL) {
delete pointer_;
}
}
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >::SmartPtr(con st SmartPtr<T, OwnershipPolicy >&
otherPointer) {
#ifdef DEBUG
std::cout << "SmartPtr Copy-Constructor\n";
#endif
copyPtr(otherPo inter);
}
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >& SmartPtr<T, OwnershipPolicy >::operator=(co nst
SmartPtr& otherSmartPtr) {
#ifdef DEBUG
std::cout << "SmartPtr Assignment Operator\n";
#endif
copyPtr(otherSm artPtr);
return *this;
}
template <class T, template <class> class OwnershipPolicy >
T& SmartPtr<T, OwnershipPolicy >::operator*( ) const {
return *pointer_;
}
template <class T, template <class> class OwnershipPolicy >
T* SmartPtr<T, OwnershipPolicy >::operator->() const {
return pointer_;
}
template <class T, template <class> class OwnershipPolicy >
void SmartPtr<T, OwnershipPolicy >::copyPtr(cons t SmartPtr<T,
OwnershipPolicy >& otherPointer) {
if (copy(otherPoin ter)) {
if (dispose() && pointer_!=NULL) {
delete pointer_;
}
}
pointer_=otherP ointer.pointer_ ;
}
template <class T>
bool RefCount<T>::co py(const SmartPtr<T, RefCount<T> >& otherPointer) {
#ifdef DEBUG
std::cout << "RefCount:: copy - count="<< (*count_) <<"\n";
#endif
count_=otherPoi nter.count_;
++(*count_);
return true;
}
template <class T>
void RefCount<T>::in itOwnership() {
count_=new long(1);
#ifdef DEBUG
std::cout << "RefCount::init Ownership - count="<< (*count_) <<"\n";
#endif
}
template <class T>
bool RefCount<T>::di spose() {
--(*count_);
#ifdef DEBUG
std::cout << "RefCount::disp ose - count="<< (*count_) <<"\n";
#endif
if (*count_==0) {
return true;
}
return false;
}
class LongWrapper {
private:
long x;
public:
LongWrapper(lon g l): x(l) {}
long get() { return x;}
};
bool testSmartPtr() {
LongWrapper *lp1=new LongWrapper(1);
/* HERE IS THE ERROR */
SmartPtr<LongWr apper, RefCount> *p1=new SmartPtr<LongWr apper,
RefCount>(lp1);
return true;
}
int main(int argc, char *argv[])
{
std::cout << "Hello, World!" << std::endl;
testSmartPtr();
return EXIT_SUCCESS;
}
during this. The program compiles fine - but I get a linker error:
test.o(.text+0x 3e): In function `testSmartPtr() ':
/home/tobias/project/Heart/heartofoak/test.cpp:23: undefined reference to
`SmartPtr<LongW rapper, RefCount>::Smar tPtr[in-charge](LongWrapper*)'
collect2: ld returned 1 exit status
I think the linker does not find the Constructor of the
SmartPointer<Lo ngWrapper, RefCount>.
The Code:
template <class T, template <class> class OwnershipPolicy >
class SmartPtr : public OwnershipPolicy <T> {
public:
explicit SmartPtr(T* pointer);
SmartPtr(const SmartPtr<T, OwnershipPolicy >& otherPointer);
SmartPtr& operator=(const SmartPtr<T, OwnershipPolicy >& otherSmartPtr);
~SmartPtr();
T& operator*() const;
T* operator->() const;
private:
void copyPtr(const SmartPtr<T, OwnershipPolicy >& otherPointer);
SmartPtr();
T* pointer_;
};
/* Policy Klassen fuer Kopien */
template <class T>
class RefCount {
private:
long *count_;
void initOwnership() ;
bool dispose();
bool copy(const SmartPtr<T, RefCount<T> >&);
friend class SmartPtr<T, RefCount>;
};
#include "smartptr.h "
#define DEBUG 1
#ifdef DEBUG
#include <iostream>
#endif
// not allowed, thus declared private and not implemented
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >::SmartPtr() {
}
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >::SmartPtr(T * pointer): pointer_(pointe r) {
#ifdef DEBUG
std::cout << "SmartPtr Constructor\n";
#endif
initOwnership() ;
}
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >::~SmartPtr( ){
#ifdef DEBUG
std::cout << "SmartPtr Destructor\n";
#endif
if (dispose() && pointer_!=NULL) {
delete pointer_;
}
}
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >::SmartPtr(con st SmartPtr<T, OwnershipPolicy >&
otherPointer) {
#ifdef DEBUG
std::cout << "SmartPtr Copy-Constructor\n";
#endif
copyPtr(otherPo inter);
}
template <class T, template <class> class OwnershipPolicy >
SmartPtr<T, OwnershipPolicy >& SmartPtr<T, OwnershipPolicy >::operator=(co nst
SmartPtr& otherSmartPtr) {
#ifdef DEBUG
std::cout << "SmartPtr Assignment Operator\n";
#endif
copyPtr(otherSm artPtr);
return *this;
}
template <class T, template <class> class OwnershipPolicy >
T& SmartPtr<T, OwnershipPolicy >::operator*( ) const {
return *pointer_;
}
template <class T, template <class> class OwnershipPolicy >
T* SmartPtr<T, OwnershipPolicy >::operator->() const {
return pointer_;
}
template <class T, template <class> class OwnershipPolicy >
void SmartPtr<T, OwnershipPolicy >::copyPtr(cons t SmartPtr<T,
OwnershipPolicy >& otherPointer) {
if (copy(otherPoin ter)) {
if (dispose() && pointer_!=NULL) {
delete pointer_;
}
}
pointer_=otherP ointer.pointer_ ;
}
template <class T>
bool RefCount<T>::co py(const SmartPtr<T, RefCount<T> >& otherPointer) {
#ifdef DEBUG
std::cout << "RefCount:: copy - count="<< (*count_) <<"\n";
#endif
count_=otherPoi nter.count_;
++(*count_);
return true;
}
template <class T>
void RefCount<T>::in itOwnership() {
count_=new long(1);
#ifdef DEBUG
std::cout << "RefCount::init Ownership - count="<< (*count_) <<"\n";
#endif
}
template <class T>
bool RefCount<T>::di spose() {
--(*count_);
#ifdef DEBUG
std::cout << "RefCount::disp ose - count="<< (*count_) <<"\n";
#endif
if (*count_==0) {
return true;
}
return false;
}
class LongWrapper {
private:
long x;
public:
LongWrapper(lon g l): x(l) {}
long get() { return x;}
};
bool testSmartPtr() {
LongWrapper *lp1=new LongWrapper(1);
/* HERE IS THE ERROR */
SmartPtr<LongWr apper, RefCount> *p1=new SmartPtr<LongWr apper,
RefCount>(lp1);
return true;
}
int main(int argc, char *argv[])
{
std::cout << "Hello, World!" << std::endl;
testSmartPtr();
return EXIT_SUCCESS;
}
Comment