Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Qt Academy Launch in California!

    [SOLVED]overloading operator <<,>>

    C++ Gurus
    3
    8
    6222
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Q
      qxoz last edited by

      Hi everybody!
      I can't figure out what is wrong in following simple code:
      @#ifndef GLOBAL_H
      #define GLOBAL_H
      #include <QString>
      #include <QDataStream>
      #include <QDateTime>

      enum SwapUserType {UT_USER, UT_ADMIN, UT_NOTAUTORIZED};

      /**
      Declaring autorizing request class
      */

      class uAutorizingRequest
      {
      public:
      QString UserName;
      QString Password;
      };
      QDataStream &operator <<(QDataStream &out,const uAutorizingRequest &autorize);
      QDataStream &operator >>(QDataStream &in, uAutorizingRequest &autorize);

      QDataStream &operator <<(QDataStream &out,const uAutorizingRequest &autorize)
      {
      out << autorize.UserName << autorize.Password;
      return out;
      }

      QDataStream &operator >>(QDataStream &in, uAutorizingRequest &autorize)
      {
      autorize = uAutorizingRequest();
      in >> autorize.UserName >> autorize.Password;
      return in;
      }

      /**
      Declaring autorizing answer class
      */

      class uAutorizingAnswer
      {
      public:
      SwapUserType UserType;
      QDateTime ServerDateTime;
      };
      QDataStream &operator <<(QDataStream &out,const uAutorizingAnswer &autorize);
      QDataStream &operator >>(QDataStream &in, uAutorizingAnswer &autorize);

      QDataStream &operator <<(QDataStream &out,const uAutorizingAnswer &autorize)
      {
      out << (quint8)autorize.UserType << autorize.ServerDateTime;
      return out;
      }

      QDataStream &operator >>(QDataStream &in, uAutorizingAnswer &autorize)
      {
      autorize = uAutorizingAnswer();
      quint8 temp;
      in >> temp >> autorize.ServerDateTime;
      autorize.UserType = (SwapUserType)temp;
      return in;
      }

      #endif // GLOBAL_H

      @

      Error messages are:
      @c:/QtSDK/Desktop/Qt/4.8.1/mingw/include/QtCore/qatomic_i386.h:113: multiple definition of operator<<(QDataStream&, uAutorizingRequest const&)' debug/main.o:d:\BotirAxmedov\projects\TradeSoftware\TradeClient/../global/global.h:24: first defined here debug/tradeclient.o: In function ZrsR11QDataStreamR18uAutorizingRequest':
      d:\BotirAxmedov\projects\TradeSoftware\TradeClient/../global/global.h:30: multiple definition of operator>>(QDataStream&, uAutorizingRequest&)' debug/main.o:d:\BotirAxmedov\projects\TradeSoftware\TradeClient/../global/global.h:30: first defined here debug/tradeclient.o: In function ZlsR11QDataStreamRK17uAutorizingAnswer':@

      Can you tell what i'm doing wrong?
      Thank you!

      1 Reply Last reply Reply Quote 0
      • G
        guziemic last edited by

        Hi,

        In my opinion body of operator is wrong. It should be like this

        @
        QDataStream &operator >>(QDataStream &in, uAutorizingRequest &autorize)
        {
        in >> autorize.UserName >> autorize.Password;
        return in;
        }
        @

        I think that you do not have to create new object and write directly to autorize object that is passed as an parameter to function.

        1 Reply Last reply Reply Quote 0
        • L
          lgeyer last edited by

          You've defined operator<< and operator>> in the header. The header is included at least twice, in main and tradeclient, so is the definition.

          This is the reason definitions are usually made in source files, which is the solution to your problem.

          1 Reply Last reply Reply Quote 0
          • G
            guziemic last edited by

            Actually, header file can be included as many time as need, and the preprocessor statements

            @
            #ifndef GLOBAL_H
            #define GLOBAL_H
            ...
            #endif // GLOBAL_H
            @

            works as information to include in or not. This is done during compilation. In the snippet of code I see that definition of class is made correctly.

            In addition, if you create library for someone else you will not give him source files. You will provide library + header files.

            1 Reply Last reply Reply Quote 0
            • Q
              qxoz last edited by

              Thank you for reply!
              I move the definitions into the source file and it's worked.
              But i'm still can't understand why the preprocessor statements
              @#ifndef GLOBAL_H
              #define GLOBAL_H
              ...
              #endif // GLOBAL_H@
              not work in this case.

              1 Reply Last reply Reply Quote 0
              • L
                lgeyer last edited by

                [quote author="guziemic" date="1349771045"]Actually, header file can be included as many time as need...[/quote]Yes, this is exactly the problem.

                [quote author="guziemic" date="1349771045"]... and the preprocessor statements works as information to include in or not.[/quote]No, this is a misconception on how include guards work. They will prevent multiple inclusion in the same file, but not in multiple files.

                Including global.h in main.cpp twice will not lead to multiple inclusion. But including global.h in main.cpp and tradeclient.cpp will lead to a definition of operator<< and operator>> in main.cpp and tradeclient.cpp. The compiler will generate object code in both, main.o and tradeclient.o.

                Keep in mind that main.cpp and tradeclient.cpp are seperate translation units. The compiler doesn't know what has been already defined in another translation unit.

                When the linker then tries to link main.o and tradeclient.o into a single object file it rightly complains that there are multiple definitions for operator<< and operator>>.

                This is the reason you should only place declarations in headers, but not definitions.
                [quote author="guziemic" date="1349771045"]In addition, if you create library for someone else you will not give him source files. You will provide library + header files.[/quote]That's another reason not to include source code into header files, isn't it ;-)

                The definition (or implementation) of operator<< and operator>> will be compiled to object code and then linked to the library. There is no need to provide the source code when distributing.

                1 Reply Last reply Reply Quote 1
                • Q
                  qxoz last edited by

                  Thanks Lukas
                  Thanks guziemic
                  It's clear now.

                  1 Reply Last reply Reply Quote 0
                  • L
                    lgeyer last edited by

                    You are welcome. Feel free to edit the thread title to ‘[Solved] …’ to indicate that there is a solution inside.

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post