Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

how can i use the template in Separation Model??

Posted on 2003-10-29
4
Medium Priority
?
310 Views
Last Modified: 2010-04-02
//Array.h
#include <iostream>
using std::ostream;
using std::cout;
using std::endl;

template <class elemType> class Array;
template <class elemType> ostream&
          operator<<( ostream &, Array<elemType> & );

template <class elemType>
class Array {
public:
    // explicit Array( int sz = DefaultArraySize )
    Array( int sz = DefaultArraySize )
         { init( 0, sz ); }

    Array( const elemType *ar, int sz )
         { init( ar, sz ); }

    Array( const Array &iA )
         { init( iA._ia, iA._size ); }

    virtual ~Array() { delete[] _ia; }

    Array& operator=( const Array & );
    int size() const { return _size; }

    virtual elemType& operator[]( int ix ) { return _ia[ix]; }
    virtual elemType  operator[]( int ix ) const { return _ia[ix]; }

    elemType at( int ix ) const { return _ia[ ix ]; }

    virtual ostream &print( ostream& os = cout ) const;
    virtual void grow();

protected:
    void init( const elemType*, int );

    // static const int DefaultArraySize = 12;
    static const int DefaultArraySize;
    int       _size;
    elemType *_ia;
};

template <class Type>
        Type min( Type a, Type b ) {
                return a < b ? a : b;
}

template <class elemType>
        void swap( Array<elemType> &array, int i, int j )
{
        elemType tmp = array[ i ];
        array[ i ] = array[ j ];
        array[ j ] = tmp;
}

//Array.cpp
#include "array.h"
#include <cassert>

template <class elemType>
  const int Array<elemType>::DefaultArraySize = 12;

template <class elemType>
    void Array<elemType>::init( const elemType *array, int sz )
{
    if ( ! array ) { _size = 0; _ia = 0; }
    if ( sz < 1 ) sz = 1;

    _size = sz;
    _ia = new elemType[ _size ];

    if ( ! array ) return;

    for ( int ix = 0; ix < _size; ++ix )
       _ia[ ix ] = array[ ix ];
}

template <class elemType> Array<elemType>&
    Array<elemType>::operator=( const Array<elemType> &iA )
{
    if ( this == &iA )
         return *this;

    delete[] _ia;
    init( iA._ia, iA._size );
    return *this;
}

template <class elemType> ostream&
    operator<<( ostream &os, Array<elemType> &ar )
{
    return ar.print( os );
}

template <class elemType>
    ostream& Array<elemType>::print( ostream &os ) const
{
    const int lineLength = 12;
    os << "( " << _size << " )< ";

    for ( int ix = 0; ix < _size; ++ix )
    {
          if ( ix % lineLength == 0 && ix )
               os << "\n\t";

          os << _ia[ ix ];
          // don't generate comma for last item on line
          // nor for the last element of the array
          if ( ix % lineLength != lineLength-1 && ix != _size-1 )
               os << ", ";
    }

    os << " >\n";
    return os;
}

template <class elemType>
    void Array<elemType>::grow()
{
    elemType *oldia = _ia;
    int oldSize = _size;

    _size = oldSize + oldSize/2 + 1;
    _ia   = new elemType[_size];

    int ix;
    for ( ix = 0; ix < oldSize; ++ix)
          _ia[ix] = oldia[ix];

    for ( ; ix < _size; ++ix )
       _ia[ix] = elemType();

    delete[] oldia;
}

//Algo.cpp
template <class elemType>
        void sort( Array<elemType> &array, int low, int high ) {
        if ( low < high ) {
                int lo = low;
                int hi = high + 1;
                elemType elem = array[lo];

                for (;;) {
                        while ( min( array[++lo], elem ) != elem && lo < high ) ;
                        while ( min( array[--hi], elem ) == elem && hi > low ) ;

                        if (lo < hi)
                                swap( array, lo, hi );
                        else break;
                }

                swap( array, low, hi );
                sort( array, low, hi-1 );
                sort( array, hi+1, high );
        }
}

template <class elemType>
        void display( Array<elemType> &array )
{ // display format: < 0 1 2 3 4 5 >

        cout << "< ";
        for ( int ix = 0; ix < array.size(); ++ix )
                cout << array[ix] << " ";
        cout << ">\n";
}

//the main program
#include <string>
using std::string;

#include "Array.h"
#include "Algo.cpp"

double da[10] = {
        26.7, 5.7, 37.7, 1.7, 61.7, 11.7, 59.7,
        15.7, 48.7, 19.7 };

int ia[16] = {
        503, 87, 512, 61, 908, 170, 897, 275, 653,
        426, 154, 509, 612, 677, 765, 703 };

string sa[11] = {
        "a", "heavy", "snow", "was", "falling", "when",
        "they", "left", "the", "police", "station" };

int main() {

        // call the constructor to initialize arrd
        Array<double> arrd( da, sizeof(da)/sizeof(da[0]) );

        // call the constructor to initialize arri
        Array<int> arri( ia, sizeof(ia)/sizeof(ia[0]) );

        // call the constructor to initialize arrs
        Array<string> arrs( sa, sizeof(sa)/sizeof(sa[0]) );

        cout << "sort array of doubles (size == "
             << arrd.size() << ")" << endl;
        sort(arrd, 0, arrd.size()-1 );
        display(arrd);

        cout << "sort array of ints (size == "
             << arri.size() << ")" << endl;
        sort(arri, 0, arri.size()-1 );
        display(arri);

        cout << "sort array of strings (size == "
             << arrs.size() << ")" << endl;
        sort(arrs, 0, arrs.size()-1 );
         display(arrs);

        return 0;
}
but so many messages:
Compiling...
main11.cpp
Linking...
main11.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Array<double>::grow(void)" (?grow@?$Array@N@@UAEXXZ)
main11.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall Array<double>::print(class std::basic_ostream<char,struct std::char_traits<char> > &)const " (?print@?
$Array@N@@UBEAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV23@@Z)
main11.obj : error LNK2001: unresolved external symbol "protected: void __thiscall Array<double>::init(double const *,int)" (?init@?$Array@N@@IAEXPBNH@Z)
main11.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Array<int>::grow(void)" (?grow@?$Array@H@@UAEXXZ)
main11.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall Array<int>::print(class std::basic_ostream<char,struct std::char_traits<char> > &)const " (?print@?$Ar
ray@H@@UBEAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV23@@Z)
main11.obj : error LNK2001: unresolved external symbol "protected: void __thiscall Array<int>::init(int const *,int)" (?init@?$Array@H@@IAEXPBHH@Z)
main11.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Array<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::grow(void)" (?grow@?$Array@V?$basic_string@DU?$char_traits@D@std
@@V?$allocator@D@2@@std@@@@UAEXXZ)
main11.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall Array<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::print
(class std::basic_ostream<char,struct std::char_traits<char> > &)const " (?print@?$Array@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@UBEAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV23@@Z)
main11.obj : error LNK2001: unresolved external symbol "protected: void __thiscall Array<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::init(class std::basic_string<char,struct std::char_traits<char>,class
 std::allocator<char> > const *,int)" (?init@?$Array@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@IAEXPBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z)
Debug/main11.exe : fatal error LNK1120: 9 unresolved externals
Error executing link.exe.

main11.exe - 10 error(s), 0 warning(s)

how can i use the template in Separation Model??

thanks!
0
Comment
Question by:weileng_ghost
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 
LVL 30

Expert Comment

by:Axter
ID: 9647022
You can not put the template code inside a *.cpp file.

You need to put it in the header.
0
 
LVL 30

Accepted Solution

by:
Axter earned 340 total points
ID: 9647068
In order to put the code inside the *.cpp file, your compiler has to support export keyword.

There's only one compiler that support this, and VC++ is not it.

The only other way to get around this, is to include forward template class declarations inside the *.cpp file that contains the template implementation.
template foo<int>; //Forward declaration of int type for foo


Example for your code:


//Algo.cpp

template Array<int>;
template Array<double>;
template Array<string>;
template Array<int>;

template <class elemType>
       void sort( Array<elemType> &array, int low, int high ) {
       if ( low < high ) {
               int lo = low;
               int hi = high + 1;
               elemType elem = array[lo];

               for (;;) {
                       while ( min( array[++lo], elem ) != elem && lo < high ) ;
                       while ( min( array[--hi], elem ) == elem && hi > low ) ;

                       if (lo < hi)
                               swap( array, lo, hi );
                       else break;
               }

               swap( array, low, hi );
               sort( array, low, hi-1 );
               sort( array, hi+1, high );
       }
}

template <class elemType>
       void display( Array<elemType> &array )
{ // display format: < 0 1 2 3 4 5 >

       cout << "< ";
       for ( int ix = 0; ix < array.size(); ++ix )
               cout << array[ix] << " ";
       cout << ">\n";
}

0
 

Author Comment

by:weileng_ghost
ID: 9647824
ok,it works well.thanks a lot!!!
by the way,which compiler supports the separation Model?
0
 
LVL 30

Expert Comment

by:Axter
ID: 9649264
I forgot which one.  It was in the C++ Jornal magazine a few months ago.

I think it's either edg or Comeau
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question