c++ - 如何使运算符重载在友元函数中正常工作?

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

<分区>

我获取了一个免费的版权模板代码并根据自己的需要进行了修改,但仍在努力使其发挥作用。如果能帮助我理解,我将不胜感激。

问题是我真的不明白重载是如何工作的,尤其是与 >> 运算符一起工作,如下例所示。为什么要返回对象 logger在 friend &operator 函数中。我不明白如何制作void print();重载工作和与 friend 互动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, etc - types of log info.

COUT, FCOUT, CFOUT, FOUT - log to file or cout or both

已编辑:我在 3 周前解决了这个问题。感谢@zenith 的回答。如果问题再次打开,我会发布带有概述代码的解决方案,我已经更改了指向它们的点。谢谢 :)

最佳答案

I don't really understand why you return the object logger in the friend &operator function.

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

logger << logtype << text << moretext;

And how to make void print work and interact with friend overloaded operators <<.

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

logger << e_logtype << text;

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


您还缺少 #include <string> using std::string#include <iostream> .

关于c++ - 如何使运算符重载在友元函数中正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33463683/

相关文章:

c++ - 为所有 Linux 发行版编译 C++

iphone - 滚动 UITableView 标题?

c++ - 未记录的 API 和 header

c++ - 高效运营商+

c++ - 如果在 DLL 项目中使用类中的重载运算符,它们是否需要 __declspec(dllexport)?

C++ 一元 - 运算符重载无法编译

c++ - 将 LinkedList 作为元素链接到不同的 LinkedList

c++ - 将 OpenCV 链接到 XCode

c++ - mbstowcs() 因特殊字符而失败

编译C文件,运行它并使用CMAKE写入头文件