linking templates problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tobias Langner

    linking templates problem

    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;
    }

  • Victor Bazarov

    #2
    Re: linking templates problem

    "Tobias Langner" <tobias.langner @t-online.de> wrote...[color=blue]
    > I try to program a smart-pointer using policies. I rely heavyly on[/color]
    templates[color=blue]
    > 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[/color]
    [...]

    Place the template code in the header and next time start by
    searching on http://groups.google.com. "template linker error
    undefined reference" should have given you the answer way
    before you could get this one.


    Comment

    Working...