【问题标题】:C++ ostream linker error [duplicate]C ++ ostream链接器错误[重复]
【发布时间】:2015-04-16 13:46:25
【问题描述】:

我有一个链接器错误,我认为它与 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;
}

【问题讨论】:

  • 我建议您将编译器的确切输出(错误)作为帖子的一部分发布;另外,您使用的是什么编译器。
  • “我有一个错误,但我不会告诉你具体是什么,但这里有 150 多行代码供你筛选”...

标签: c++ ostream


【解决方案1】:
friend ostream& operator << (ostream& os, const NumericArray<T>& t);   

这声明了一个友元非模板operator&lt;&lt; 函数。

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

这定义了一个operator&lt;&lt; 函数模板。两者是不同的。

重载解决方案最终将您的 &lt;&lt; 指向朋友非模板函数,然后链接器抱怨它找不到它的定义 - 因为您没有提供任何定义。

【讨论】:

  • 我该如何解决?我认为由于 template 位于涵盖所有功能的类之上。
  • @kits 链接副本中有各种解决方案。如果operator&lt;&lt; 不需要访问非公共成员,甚至可以考虑完全删除朋友声明。
  • 谢谢,我尝试了这些解决方案,但它们最终为我产生了错误。
猜你喜欢
  • 2014-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
相关资源
最近更新 更多