Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
662 views
in Technique[技术] by (71.8m points)

c++ - Operator << overloading

I'm working on my project and I want to overload operator << which should print out my object on console.
Object is called "config" and in its template class it has 4 arrays called attribute1, attribute2. attribute3 and attribute4.

So far I've tried this :

#include "stdafx.h"
#include <string>
#include <iostream>

using namespace std;

template<typename T> class config
{
    T *attribute1, *attribute2, *attribute3, *attribute4;
    string attribName1, attribName2, attribName3, attribName4;
  public:
    config(void)
    {
      attribute1 = new T[3];
      attribute2 = new T[3];
      attribute3 = new T[3];
      attribute4 = new T[3];
    }   

    ~config(void)//destruktor
     {
       delete [] attribute1, attribute2, attribute3, attribute4;
     }

    //operatory
    friend ostream& operator<<(ostream &out, const config<T> &c); 
};//class ends

template <typename T> ostream& operator<<(ostream &out, const config<T> &c)
{
  for(int i=0;i<3;i++)
  {
    out<<c.attribute1[i]<<c.attribute2[i]<<c.attribute3[i]<<c.attribute2[i];
  }
  return out;
}

Whenever I try to compile it, it gives some kind of weird error, but I know the problem is in the operator.

This is the error it gives :

Error   1   error LNK2001: 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 config<double> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$config@N@@@Z)    D:DocsVisual Studio 2010Projectsproject_v2.obj  project_v2

and:

Error   2   error LNK1120: 1 unresolved externals   D:DocsVisual Studio 2010Projectsproject_v2.exe  project_v2

And line or column isnt specified.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here's one way to solve the problem.

  1. Declare the operator<< function first, before config is defined. In order to declare the function, you have to forward declare the class template.

    template <typename T> class config;
    template <typename T> std::ostream& operator<<(std::ostream &out,
                                                   const config<T> &c);
    
  2. In the class, make the function a friend by using T as the template parameter.

    friend ostream& operator<< <T>(ostream &out, const config &c);
    // Notice  this            ^^^^
    // This makes sure that operator<< <int> is not a friend of
    // config<double>. Only operator<< <double> is a friend of
    // config<double>
    

Here's a working program with those changes:

#include <string>
#include <iostream>

template <typename T> class config;
template <typename T> std::ostream& operator<<(std::ostream &out,
                                               const config<T> &c);

template <typename T> class config
{
    T *attribute1, *attribute2, *attribute3, *attribute4;
    std::string attribName1, attribName2, attribName3, attribName4;
  public:
    config(void)
    {
      attribute1 = new T[3];
      attribute2 = new T[3];
      attribute3 = new T[3];
      attribute4 = new T[3];
    }   

    ~config(void)//destructor
     {
       delete [] attribute1;
       delete [] attribute2;
       delete [] attribute3;
       delete [] attribute4;
     }

    //operator
    friend std::ostream& operator<< <T>(std::ostream &out,
                                        const config &c);
};

template <typename T> std::ostream& operator<<(std::ostream &out,
                                               const config<T> &c)
{
   for(int i=0;i<3;i++)
   {
      out << c.attribute1[i] << " "
          << c.attribute2[i] << " "
          << c.attribute3[i] << " "
          << c.attribute2[i] << std::endl;
   }
   return out;
}

int main()
{
   config<double> x;
   std::cout << x << std::endl;
}

Output:

0 0 0 0
0 0 0 0
0 0 0 0


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...