【问题标题】:How to make operator overloading work properly inside friend function? [closed]如何使运算符重载在友元函数中正常工作? [关闭]
【发布时间】:2015-11-01 15:12:55
【问题描述】:

我获取了一个免费的版权模板代码并根据自己的需要进行了修改,但仍在努力使其工作。我会很感激一些帮助理解。

问题是我并不真正理解重载是如何工作的,尤其是使用 >> 运算符,如下例所示。为什么在friend &operator 函数中返回对象logger。我不明白如何让void print(); 工作并与重载operator << 的朋友互动。

这是示例代码:

#pragma once

#include <fstream>


namespace  Log{

    class LogFile {

        public:

            enum class logType { LOG_ALWAYS=0, LOG_OKAY, LOG_ERROR, LOG_WARNING, LOG_INFO};
            enum class writeType {FOUT=0, CFOUT, FCOUT, COUT};

            explicit LogFile(string fname = "[nameError]log.txt") : numWarnings(0U), numErrors(0U)
            {
                myFile.open(fname);

                if (myFile.is_open())
                    std::cout << "Log file was created successfully!" << std::endl << std::endl;

                else
                {
                    std::cout << "Fatal Error can't create log file!" << std::endl << "Please check Application permissions" << std::endl;
                    exit(1);
                }
            }

            ~LogFile()
            {
                if (myFile.is_open())
                {
                    myFile << std::endl << std::endl;
                    myFile << numWarnings << " warnings" << std::endl;
                    myFile << numErrors << " errors" << std::endl;
                    myFile.close();
                }
            }

            friend LogFile &operator << (LogFile &logger, const logType e_logtype)
            {

                //TO DO
                //logger.myFile << tm << "|      " << memUsed << "kb added|";
                //<< "000000.000 | 0.0000kb added |"


                switch (e_logtype)
                {
                case LogFile::logType::LOG_ALWAYS:
                    logger.myFile << " ALWAYS| ";
                    break;

                case LogFile::logType::LOG_OKAY:
                    logger.myFile << "   OKAY| ";
                    break;

                case LogFile::logType::LOG_ERROR:
                    logger.myFile << "  ERROR| ";
                    ++logger.numErrors;
                    break;

                case LogFile::logType::LOG_WARNING:
                    logger.myFile << "   WARN| ";
                    ++logger.numWarnings;
                    break;

                default:
                    logger.myFile << "   INFO| ";
                    break;
                }
                return logger;
            }

            friend LogFile &operator << (LogFile &logger, const char* text)
            {
                logger.myFile << tex    t << std::endl;
                return logger;
            }

            LogFile(const LogFile &) = delete;
            LogFile &operator= (const LogFile &) = delete;



            //THIS IS MY PART


            friend void print(LogFile &logger, const char* text, const logType e_logtype, const writeType e_writetype)
            {
                switch (e_writetype)
                {
                case LogFile::writeType::FOUT:
                    logger << LogFile::logType::e_logtype << text;
                    break;

                case LogFile::writeType::FCOUT:
                case LogFile::writeType::CFOUT:
                    std::cout << text << std::endl;
                    logger << LogFile::logType::e_logtype << text;
                    break;

                case LogFile::writeType::COUT:
                default:
                    std::cout << text << std::endl;
                    break;
                }
                return;
            }

        private:

            std::ofstream myFile;
            unsigned int numWarnings;
            unsigned int numErrors;

    };

}

我们的想法是将它用作标题并在 main.cpp 中使用以下命令记录所有内容:

using namespace Log;

LogFile mylog;
mylog.print("Test...", LOG_OKAY, FCOUT);

地点:

LOG_OKAY、LOG_ERROR 等 - 日志信息类型。

COUT、FCOUT、CFOUT、FOUT - 记录到文件或 cout 或两者

已编辑:我在 3 周前解决了这个问题。感谢@zenith 的回答。如果问题再次被打开,我将使用我已更改的要点发布解决方案。谢谢:)

【问题讨论】:

  • 您所说的“工作和互动”是什么意思?它不编译吗?它不会产生预期的结果吗?预期的结果是什么?
  • 是什么让你认为有错误?这个问题问得很不好。
  • Emm 我的意思是不编译。我编辑了这个问题。
  • 你的 print 既不应该是朋友也不应该接受 LogFile 参数 - 删除两者,你会得到一个简单的成员函数,它可以让你调用 mylog.print(...)
  • @eran 但是我有logger &lt;&lt; LogFile::logType::e_logtype &lt;&lt; text; 如果我删除 LogFile 因为参数记录器将是未定义的。

标签: c++ header operator-overloading friend-function


【解决方案1】:

我真的不明白你为什么在朋友&运算符函数中返回对象logger

这样您就可以像这样链接多个调用:

logger << logtype << text << moretext;

以及如何使void print 工作并与重载operators &lt;&lt; 的朋友互动。

您可以通过删除e_logtype前面的LogFile::logType::来修复编译错误:

logger << e_logtype << text;

因为e_logtype 不是LogFile::logType 的成员,所以它是LogFile::logType 类型的对象。


您还缺少#include &lt;string&gt; using std::string#include &lt;iostream&gt;

【讨论】:

  • 谢谢。顺便说一句,我读到您不必真正#include iostream,因为它已经在 stdafx 中定义。我又糊涂了
  • stdafx.h 不是标准标头。如果有一天stdafx.h 不再包含这些呢? (通常你不应该依赖另一个标题,包括东西。)
  • Ahhhh 所以如果你想在其他地方使用标题,你应该包括那些 iostream 和 fstream?
  • @KasparSiricenko:如果stdafx.h 中包含iostreamstring,则无需包含它们。
  • @zenith: stdafx.h 用于微软 C++ 编译器的头文件预编译
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多