linking templates problem

Discussion in 'C++' started by Tobias Langner, Jul 30, 2003.

  1. 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+0x3e): In function `testSmartPtr()':
    /home/tobias/project/Heart/heartofoak/test.cpp:23: undefined reference to
    `SmartPtr<LongWrapper, RefCount>::SmartPtr[in-charge](LongWrapper*)'
    collect2: ld returned 1 exit status

    I think the linker does not find the Constructor of the
    SmartPointer<LongWrapper, 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_(pointer) {
    #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(const SmartPtr<T, OwnershipPolicy>&
    otherPointer) {
    #ifdef DEBUG
    std::cout << "SmartPtr Copy-Constructor\n";
    #endif
    copyPtr(otherPointer);
    }

    template <class T, template <class> class OwnershipPolicy>
    SmartPtr<T, OwnershipPolicy>& SmartPtr<T, OwnershipPolicy>::eek:perator=(const
    SmartPtr& otherSmartPtr) {
    #ifdef DEBUG
    std::cout << "SmartPtr Assignment Operator\n";
    #endif
    copyPtr(otherSmartPtr);
    return *this;
    }

    template <class T, template <class> class OwnershipPolicy>
    T& SmartPtr<T, OwnershipPolicy>::eek:perator*() const {
    return *pointer_;
    }


    template <class T, template <class> class OwnershipPolicy>
    T* SmartPtr<T, OwnershipPolicy>::eek:perator->() const {
    return pointer_;
    }

    template <class T, template <class> class OwnershipPolicy>
    void SmartPtr<T, OwnershipPolicy>::copyPtr(const SmartPtr<T,
    OwnershipPolicy>& otherPointer) {
    if (copy(otherPointer)) {
    if (dispose() && pointer_!=NULL) {
    delete pointer_;
    }
    }
    pointer_=otherPointer.pointer_;
    }

    template <class T>
    bool RefCount<T>::copy(const SmartPtr<T, RefCount<T> >& otherPointer) {
    #ifdef DEBUG
    std::cout << "RefCount::copy - count="<< (*count_) <<"\n";
    #endif
    count_=otherPointer.count_;
    ++(*count_);
    return true;
    }

    template <class T>
    void RefCount<T>::initOwnership() {
    count_=new long(1);
    #ifdef DEBUG
    std::cout << "RefCount::initOwnership - count="<< (*count_) <<"\n";
    #endif
    }

    template <class T>
    bool RefCount<T>::dispose() {
    --(*count_);
    #ifdef DEBUG
    std::cout << "RefCount::dispose - count="<< (*count_) <<"\n";
    #endif
    if (*count_==0) {
    return true;
    }
    return false;
    }

    class LongWrapper {
    private:
    long x;
    public:
    LongWrapper(long l): x(l) {}

    long get() { return x;}
    };


    bool testSmartPtr() {
    LongWrapper *lp1=new LongWrapper(1);
    /* HERE IS THE ERROR */
    SmartPtr<LongWrapper, RefCount> *p1=new SmartPtr<LongWrapper,
    RefCount>(lp1);


    return true;
    }

    int main(int argc, char *argv[])
    {
    std::cout << "Hello, World!" << std::endl;

    testSmartPtr();
    return EXIT_SUCCESS;
    }
     
    Tobias Langner, Jul 30, 2003
    #1
    1. Advertising

  2. "Tobias Langner" <> wrote...
    > 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+0x3e): In function `testSmartPtr()':
    > /home/tobias/project/Heart/heartofoak/test.cpp:23: undefined reference to

    [...]

    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.
     
    Victor Bazarov, Jul 30, 2003
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. murali
    Replies:
    1
    Views:
    295
    John Harrison
    Sep 2, 2003
  2. JKop
    Replies:
    3
    Views:
    479
  3. recover
    Replies:
    2
    Views:
    812
    recover
    Jul 25, 2006
  4. Replies:
    3
    Views:
    303
    siddhu
    May 7, 2007
  5. david
    Replies:
    0
    Views:
    305
    david
    Apr 15, 2008
Loading...

Share This Page