[solved] g++ 模板类中的友元函数 链接出错

[answer]
将模板类中关于友元函数的声明更改为:
    template<class ItemType>
    class GenericList
    {
    public:
        GenericList(int max);
        ~GenericList();
        int length() const;
        void add(ItemType new_item);
        bool full() const;
        void erase();
         template<class ItemType1> friend ostream& operator << (ostream& outs,const GenericList<ItemType1>& the_list);
    private:
        ItemType * item;
        int max_length;
        int current_length;
    };

[Question]
我在看 Walter Savitch的 《C++面向对象程序设计第7版》的模板类那一节时,例子程序运行出错。哪位大侠能帮我看看啊?
错误信息如下:
root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# g++ main.cpp -o main.o
In file included from main.cpp:2:0:
genericlist.h:18:88: warning: friend declaration â€˜std::ostream& listsavitch::operator<<(std::ostream&, const listsavitch::GenericList<ItemType>&) declares a non-template function [-Wnon-template-friend]
genericlist.h:18:88: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) 
/tmp/ccFUMtfR.o: In function `main':
main.cpp:(.text+0x56): undefined reference to `listsavitch::operator<<(std::basic_ostream<char, std::char_traits<char> >&, listsavitch::GenericList<int> const&)'
main.cpp:(.text+0xb8): undefined reference to `listsavitch::operator<<(std::basic_ostream<char, std::char_traits<char> >&, listsavitch::GenericList<char> const&)'
collect2: ld returned 1 exit status

代码源文件如下:
root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# ls
genericlist.cpp  genericlist.h  main.cpp
root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# vim genericlist.h
#ifndef GENERICLIST_H
#define GENERICLIST_H
#include <iostream>
using namespace std;

namespace listsavitch
{
    template<class ItemType>
    class GenericList
    {
    public:
        GenericList(int max);
        ~GenericList();
        int length() const;
        void add(ItemType new_item);
        bool full() const;
        void erase();
         friend ostream& operator <<(ostream& outs,const GenericList<ItemType>& the_list);
    private:
        ItemType * item;
        int max_length;
        int current_length;
    };

}   //listsavitch
#endif //LIST_H

root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# vim genericlist.cpp
#ifndef GENERICLIST_CPP
#define GENERICLIST_CPP
#include <iostream>
#include <cstdlib>
#include "genericlist.h"

using namespace std;

namespace listsavitch
{
    //use cstdlib;
    template<class ItemType>
    GenericList<ItemType>::GenericList(int max) : max_length(max),current_length(0)
    {
        item=new ItemType[max];
    }

    template<class ItemType>
    GenericList<ItemType>::~GenericList()
    {
        delete [] item;
    }
    
    template<class ItemType>
    int GenericList<ItemType>::length() const
    {
        return (current_length);
    }

    template<class ItemType>
    void GenericList<ItemType>::add(ItemType new_item)
    {
        if(full())
        {
            cout << "Error: adding to a full list.\n";
            exit(1);
        }
        else
        {
            item[current_length]=new_item;
            current_length=current_length+1;
        }
    }

    template<class ItemType>
    bool GenericList<ItemType>::full() const
    {
        return (current_length==max_length);
    }

    template<class ItemType>
    void GenericList<ItemType>::erase()
    {
        current_length=0;
    }

    template<class ItemType>
    ostream& operator <<(ostream& outs,const GenericList<ItemType>& the_list)
    {
        for(int i=0;i<the_list.current_length;i++)
            outs << the_list.item[i] << endl;
        return outs;
    }

}
#endif

root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# vim main.cpp
#include <iostream>
#include "genericlist.h"
#include "genericlist.cpp"
using namespace std;
using namespace listsavitch;

int main()
{
    GenericList<int> first_list(2);
    first_list.add(1);
    first_list.add(2);
    cout << "first_list = \n"
        << first_list;

    GenericList<char> second_list(10);
    second_list.add('A');
    second_list.add('B');
    second_list.add('C');
    cout << "second_list = \n"
        << second_list;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值