C ++ ostream链接器错误

时间:2015-02-16 05:01:09

标签: c++ ostream

我有一个链接器错误,我认为这与ostream有关,但我不确定。该错误发生在main()的最后一行。我花了很多时间来解决这个问题,如果有人想出任何我会感激的话。

//NumericArray.h
//create numeric array

#ifndef NUMERICARRAY_H
#define NUMERICARRAY_H
#include "array.h"

namespace Joe
{
    namespace Containers
    {
        template<typename T>
        class NumericArray: public Array<T>
        {
        public:
            NumericArray<T>();    //default constructor
            NumericArray<T>(int i);    //constructor with one argument
            ~NumericArray<T>();    //destructor
            NumericArray<T>(const NumericArray<T>& source);    //copy constructor
            NumericArray<T>& operator = (const NumericArray<T>& arr1);    //assignment operator
            NumericArray<T>& operator * (double factor) const;    //scale
            NumericArray<T>& operator + (const NumericArray<T>& arr2) const;    //add
            T dotProduct(const NumericArray<T>& na) const;    //dot product
            friend ostream& operator << (ostream& os, const NumericArray<T>& t);    //send to ostream (friend)
        };
    }
}
#ifndef NUMERICARRAY_CPP
#include "NumericArray.cpp"
#endif
#endif

//NumericArray.cpp
//create numeric array
//mod dates:
//2.14.15

#ifndef NUMERICARRAY_CPP
#define NUMERICARRAY_CPP
#include "array.h"
#include "OutOfBoundsException.h"
#include "NumericArray.h"

using namespace Joe::CAD;

namespace Joe
{
    namespace Containers
    {
        template<typename T>
        NumericArray<T>::NumericArray() : Array<T>::Array()    //default constructor
        {
        }

        template<typename T>
        NumericArray<T>::NumericArray(const int i) : Array<T>(i) {}    //constructor with one argument


        template<typename T>
        NumericArray<T>::~NumericArray()    //destructor
        {
        }

        template<typename T>
        NumericArray<T>::NumericArray(const NumericArray& source) : Array<T>(source) {}    //copy constructor


        template<typename T>
        NumericArray<T>& NumericArray<T>::operator = (const NumericArray<T> &source)    //assignment operator
        {
            if (this == &source)
                return *this;
            Array<T>::operator = (source);
            return *this;
        }

        template<typename T>
        NumericArray<T>& NumericArray<T>::operator * (double factor) const    //scale
        {
            NumericArray<T> scale(Array<T>::Size());
            for (int i = 0; i < Array<T>::Size(); i++)
                scale[i] = factor * ((*this).GetElement(i));
            return scale;
        }

        template<typename T>
        NumericArray<T>& NumericArray<T>::operator + (const NumericArray<T>& arr) const    //add
        {
            if (Array<T>::Size() != arr.Size()) throw OutOfBoundsException();
            NumericArray<T> temp(Array<T>::Size());
            for (int i = 0; i < Array<T>::Size(); i++) {
                temp[i] = arr + (*this)[i];
            }
            return temp;
        }

        template<typename T>
        T NumericArray<T>::dotProduct(const NumericArray<T>& na) const    //compute dot product
        {
            double result = 0;
            for (int i = 0; i < Array<T>::Size(); i++)
                result += NumericArray<T>::GetElement(i) * (na.GetElement(i));
            return result;
        }

        template<typename T>
        ostream& operator << (ostream& os, const NumericArray<T>& t)    //send to ostream
        {
            os << t.NumericArray() << endl;
            return os;
        }
    }
}
#endif

//test.cpp
//testing templates

#include "array.h"
#include "point.h"
#include <iostream>
#include "ArrayException.h"
#include "OutOfBoundsException.h"
#include "NumericArray.h"

using namespace std;
using namespace Joe::Containers;

int main()
{
    NumericArray<double> doubArray1;    //default constructor

    NumericArray<double> doubArray2(3);    //initialize array
    for (int i = 0; i < 3; i++) {
        doubArray2[i] = rand() % 100 + 1;
        cout << doubArray2[i] << endl;
    } cout << endl;

    NumericArray<double> doubArray3(3);    //initialize array
    for (int i = 0; i < 3; i++) {
        doubArray3[i] = rand() % 100 + 1;
        cout << doubArray3[i] << endl;
    } cout << endl;

    NumericArray<double> doubArray4(doubArray3);    //test copy constructor
    cout << doubArray4.GetElement(1) << endl << endl;

    doubArray1 = doubArray2;    //test assignment operator
    for (int i = 0; i < 3; i++)
        cout << doubArray1[i] << endl;

    doubArray4 = doubArray2 * 3;
    cout << doubArray4 << endl;

    return 0;
}

1 个答案:

答案 0 :(得分:2)

friend ostream& operator << (ostream& os, const NumericArray<T>& t);   

这声明了一个朋友非模板operator<<函数。

template<typename T>
ostream& operator << (ostream& os, const NumericArray<T>& t)    //send to ostream
{
    os << t.NumericArray() << endl;
    return os;
}

这定义了operator<<函数模板。两者不同。

重载决策最终会将你的<<指向朋友的非模板函数,然后链接器会抱怨它无法找到它的定义 - 因为你没有提供它。