链接器错误与ostream

时间:2011-12-08 05:24:10

标签: c++

所以我又回来了。我不确定一天中我们可以提出多少问题是否有限制所以如果我问得太多我很抱歉但是我有一个项目要做,没有更多的课时要问教授所以我我转向你们。

无论如何,我的问题是重载输入和输出运算符。我觉得我做得对,但我收到一个链接器错误,我不知道如何解决。这可能是一个简单的错误,但现在就是这样。

有人可以告诉我这次我做了什么吗?提前感谢您提供的任何帮助。

编辑:这里有更多信息。我正在使用Visual Studio 2010,据我所知,我没有改变任何关于库依赖关系的东西,但它是可能的。 这是我的整个头文件,其中包含此类的所有代码:在文件 FixedStr.h

#ifndef FIXEDSTR_H
#define FIXEDSTR_H

#include <string>
#include <iostream>

using namespace std;

template <int N>
    class FixedStr
    {
    public:
                                    FixedStr        ();
                                    FixedStr        (const FixedStr<N> &);
                                    FixedStr        (const string &);
                                    ~FixedStr       ();
                FixedStr<N> &       Copy            (const FixedStr<N> &);
                FixedStr<N> &       Copy            (const string &);
                int                 Size            (const FixedStr<N> &);
                FixedStr<N> &       operator =      (const FixedStr<N> &);
                FixedStr<N> &       operator =      (const string &);
                char                operator []     (int);
                const char          operator []     (int) const;

    friend      ostream &           operator <<     (ostream &, const FixedStr<N> &);

    private:
        string Data;

    };

template <int N>
    FixedStr<N>::FixedStr ()
    {
    }

template <int N>
    FixedStr<N>::~FixedStr ()
    {
    }

template <int N>
    FixedStr<N>::FixedStr (const FixedStr<N> & FStr)
    {
        Data = FStr.Data;
    }

template <int N>
    FixedStr<N>::FixedStr (const string & Str)
    {
        if (Str.length() == N)
            Data = Str;
    }

template <int N>
    inline FixedStr<N> & FixedStr<N>::Copy (const FixedStr<N> & F)
    {
        Data = F.Data;
        return *this;
    }

template <int N>
    inline FixedStr<N> & FixedStr<N>::Copy (const string & Str)
    {
        if (Str.length() == N)
            Data = Str;
    }

template <int N>
    inline FixedStr<N> & FixedStr<N>::operator= (const FixedStr<N> & F)
    {
        return Copy (F);
    }

template <int N>
    inline FixedStr<N> & FixedStr<N>::operator= (const string & Str)
    {
        return Copy (Str);
    }

template <int N>
    inline int FixedStr<N>::Size (const FixedStr<N> &)
    {
        return N;
    }

template <int N>
    inline char FixedStr<N>::operator[] (int i)
    {
        return Data[i];
    }

template <int N>
    inline const char FixedStr<N>::operator[] (int i) const
    {
        return Data[i];
    }
template <int N>
    ostream & operator << (ostream & out, const FixedStr<N> & F)
    {
        return out << F.Data;
    }

#endif

以下是错误:Main.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class FixedStr<5> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$FixedStr@$04@@@Z) referenced in function _main

以下是我正在测试的主要内容:在文件 Main.cpp

using namespace std;

#include "FixedStr.h"
#include "DigitStr.h"

    void main ()
    {
        string Str = "12345";
        FixedStr<5> FStr1 (Str);
        DigitStr<5> DStr;
        DStr.Copy (FStr1);
        DStr.Copy (Str);

        cout << FStr1;
    }

还有一个名为 DigitStr.h 的子类,如下所示:

#ifndef DIGITSTR_H
#define DIGITSTR_H

#include <cctype>
#include "FixedStr.h"

template <int N>
class DigitStr: public FixedStr<N>
{
public:

        enum                Exceptions {NON_DIGIT_EXCEPTION};

                            DigitStr    ();
                            DigitStr    (const DigitStr &);
                            DigitStr    (const FixedStr<N> &);
                            DigitStr    (const string &);
                            ~DigitStr   ();
            DigitStr<N> &   Copy        (const FixedStr<N> &);
            DigitStr<N> &   Copy        (const string &);

private:

};
template <int N>
    DigitStr<N>::DigitStr ()
    {
    }

template <int N>
    DigitStr<N>::DigitStr (const DigitStr & DStr): FixedStr (DStr)
    {
    }

template <int N>
    DigitStr<N>::DigitStr (const FixedStr<N> & FStr): FixedStr (FStr)
    {
        for (int i=0; i<N; i++)
        {
            if (isdigit(FStr[i]) == 0)
                throw NON_DIGIT_EXCEPTION;

            else;
        }
    }

template <int N>
    DigitStr<N>::DigitStr (const string & Str): FixedStr (Str)
    {
        for (int i=0; i<N; i++)
        {
            if (isdigit(Str[i]) == 0)
                throw NON_DIGIT_EXCEPTION;

            else;
        }
    }

template <int N>
    DigitStr<N>::~DigitStr ()
    {
    } 

template <int N>
    DigitStr<N> & DigitStr<N>::Copy (const FixedStr<N> & FStr)
    {
        for (int i=0; i<N; i++)
        {
            if (isdigit(FStr[i]) == 0)
                throw NON_DIGIT_EXCEPTION;

            else;
        }

        *this = FStr;
        return *this;
    } 

template <int N>
    DigitStr<N> & DigitStr<N>::Copy (const string & Str)
    {
        for (int i=0; i<N; i++)
        {
            if (isdigit(Str[i]) == 0)
                throw NON_DIGIT_EXCEPTION;

            else;
        }

        *this = Str;
        return *this;
    }

#endif

此外,我还不知道编译命令是什么。我只是进入项目菜单并进行编译,然后在VS 2010的Build菜单下完成Build。

编辑:我也尝试重置Visual Studio中的所有设置无济于事。问题似乎只是定义而不是实际方法,因为注释掉该方法并没有解决问题。

3 个答案:

答案 0 :(得分:2)

替换

friend ostream& operator<< (ostream &, const FixedStr<N> &);

template<int N> friend ostream& operator<< (ostream &, const FixedStr<N> &);

答案 1 :(得分:0)

这样的模板函数定义不能在单独的翻译单元中定义。这是C ++模板工作方式的烦人限制。有一个export关键字可以提供帮助,但它实际上并没有按预期的那样做。

operator<<的定义直接放入头文件中(这很好,不会导致多个符号定义错误,同样是因为模板的工作方式),或者通过{{1}间接地将它放在那里来自另一个文件(为了组织目的,不要给它#include文件结尾 - 虽然编译器并不真正关心你的文件扩展名;按照惯例,大多数人使用.cpp.i这样的文件。)

顺便说一下,.inl类型不是来自std::string。那是一个C头。它来自<string.h>。如果它适合你,那只是巧合(许多<string>的实现包括<iostream>。另外,考虑在头文件中使用<string>而不是<iosfwd>来改善编译时间(虽然这不会对您有所帮助,因为您需要模板实现的完整<iostream>标题。)

答案 2 :(得分:0)

你的主要职能在哪里?

您的代码似乎正确无误。它在我的机器上编译没有任何错误。

您可能想要检查要链接的库。如果使用Visual Studio进行编译,则默认设置应具有正确的库,除非您已篡改IDE的属性。

如果我无法解决链接器错误,我通常会使用一个名为Depends.exe的工具来识别它找不到的库。找到库并在项目中添加适当的路径后,您应该能够正确编译它。