什么是引用复制构造函数?

根据构造Log对象的方式,我收到一个编译器错误,指出我正在尝试引用一个已删除的函数(复制构造函数):

C:\ Projects \ Logger \ src \ Logger.cpp(34,1):错误C2280:“ Logger :: Log :: Log(const Logger :: Log&)”:尝试引用已删除的函数[C:\ Projects \ Logger \ build \ Logger.vcxproj]

预计我的Log对象已隐式删除了复制构造函数,因为:

T具有无法复制的非静态数据成员(已删除,不可访问或模棱两可的复制构造函数);

这是有道理的,因为删除了std::ofstream它的副本构造函数

我不明白的是为什么根本要调用复制构造函数。用赋值运算符调用复制构造函数进行构造有什么用?我正在使用MSVC进行编译,是否有一些我未使用的编译器标志无法优化某些行为?例如,构造临时对象,然后将构造复制到命名对象中foo

如下面的代码块所示,只有一个构造函数定义。

#include <iostream>
#include <string>
#include <fstream>
#include "Logger.h"
#include "LoggerConfig.h"

Logger::Log::Log(std::string file) : filename{ file }
{
    logFile = std::ofstream(filename, std::ios::out);
    if (logFile.is_open())
    {
        logFile << "This is a log.\n";
    }
    else
    {
        std::cout << "Unable to open filename: " << filename << '\n';
    }

}

Logger::Log::~Log()
{
    // Wait and take write mutex

    // Close file
}

int main()
{
    // report version
    std::cout << " Version " << LOGGER_VERSION_MAJOR << "."
              << LOGGER_VERSION_MINOR << std::endl;

    Logger::Log foo = Logger::Log::Log("sample.log"); // C2280: attemping to reference a deleted function
    //Logger::Log foo("sample.log"); // Works!
    //Logger::Log foo{"sample.log"}; // Works!

    foo.Write(Logger::Log::Level::INFO, "Testing", 123, "hahaha");

    return 0;
}

类接口logger.h如下:

#pragma once

namespace Logger
{
    class Log
    {
    private:
        std::string filename;
        std::ofstream logFile;

    public:
        enum class Level
        {
            DEBUG,
            INFO,
            WARNING,
            ERROR
        };

        Log(std::string file);
        ~Log();

        template<typename T>
        void Write(Level lvl, T arg)
        {
            logFile << arg;
            return;
        }

        template<typename T, typename... Args>
        void Write(Level lvl, T firstArg, Args... args)
        {
            logFile << firstArg;
            Write(lvl, args...);
            return;
        }
    };
}
奥马尔·加努(Omar Ghannou)

不仅仅涉及不必要的副本和C ++ 17,我们知道

   Logger::Log foo("sample.log"); 

正常工作,但为什么这标志C2280错误

   Logger::Log foo = Logger::Log::Log("sample.log");

问题出在类中的ofstream中,我得到了您的代码,并对其进行了编译,我对ofstream对象有疑问,我删除了它,并且它也能正常工作,我使它的指针也能正常工作,然后我尝试了码:

 std::ofstream s =  std::ofstream("sample.log", std::ios::out);
 std::ofstream k;
 k = s;

我收到此错误E1776函数“ std :: basic_ofstream <_Elem,_Traits> :: operator =(const std :: basic_ofstream <_Elem,_Traits>&)[with _Elem = char,_Traits = std :: char_traits]”(声明为不能引用“ C:\ Program Files(x86)\ Microsoft Visual Studio \ 2019 \ Enterprise \ VC \ Tools \ MSVC \ 14.25.28610 \ include \ fstream”的行1080-这是一个已删除的函数

这意味着流阻止复制构造函数和= operator避免访问相同的数据(文件),当您通过此行调用复制构造函数时,代码中就是这种情况

 Logger::Log foo = Logger::Log::Log("sample.log");

隐式地使用默认的复制构造函数,它对每个拥有的对象或原始类型使用= operator逐字段复制,这是ofstream的情况,它防止= operator然后编译器通过调用已删除的函数错误进行标记-

要解决此问题,您可以使用原始指针或智能指针声明ofstream指针并管理内存,也可以使用自定义创建move构造函数版本-这也会删除类中的默认复制构造函数-并尝试避免使用不同的流访问相同的数据。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

复制或引用构造函数?

来自分类Dev

为什么复制构造函数的参数是引用而不是指针?

来自分类Dev

为什么复制构造函数的参数是引用而不是指针?

来自分类Dev

为什么复制构造函数无法“复制”

来自分类Dev

为什么在此类中复制构造函数,operator =和引用具有编译问题

来自分类Dev

为什么在此类中复制构造函数,operator =和引用具有编译问题

来自分类Dev

为什么调用复制构造函数而不是移动构造函数?

来自分类Dev

为什么选择复制构造函数而不是移动构造函数

来自分类Dev

为什么调用复制构造函数而不是移动构造函数?

来自分类Dev

什么时候调用复制构造函数或赋值构造函数?

来自分类Dev

为什么选择复制构造函数而不是移动构造函数

来自分类Dev

为什么不调用复制构造函数

来自分类Dev

为什么复制构造函数被调用?

来自分类Dev

为什么复制构造函数被调用?

来自分类Dev

std :: thread通过引用传递调用复制构造函数

来自分类Dev

C ++:右值引用构造函数和复制删除

来自分类Dev

引用具有禁用的复制构造函数/分配的对象

来自分类Dev

std :: thread通过引用传递调用复制构造函数

来自分类Dev

为什么在函数返回时不调用复制构造函数?

来自分类Dev

为什么需要复制构造函数,何时在Java中使用复制构造函数

来自分类Dev

为什么需要复制构造函数,何时在Java中使用复制构造函数

来自分类Dev

javascript什么时候引用构造函数中使用的函数?

来自分类Dev

javascript什么时候引用构造函数中使用的函数?

来自分类Dev

复制构造函数

来自分类Dev

强制复制构造函数

来自分类Dev

复制构造函数

来自分类Dev

意外的复制构造函数

来自分类Dev

复制构造函数的参数

来自分类Dev

复制构造函数

Related 相关文章

  1. 1

    复制或引用构造函数?

  2. 2

    为什么复制构造函数的参数是引用而不是指针?

  3. 3

    为什么复制构造函数的参数是引用而不是指针?

  4. 4

    为什么复制构造函数无法“复制”

  5. 5

    为什么在此类中复制构造函数,operator =和引用具有编译问题

  6. 6

    为什么在此类中复制构造函数,operator =和引用具有编译问题

  7. 7

    为什么调用复制构造函数而不是移动构造函数?

  8. 8

    为什么选择复制构造函数而不是移动构造函数

  9. 9

    为什么调用复制构造函数而不是移动构造函数?

  10. 10

    什么时候调用复制构造函数或赋值构造函数?

  11. 11

    为什么选择复制构造函数而不是移动构造函数

  12. 12

    为什么不调用复制构造函数

  13. 13

    为什么复制构造函数被调用?

  14. 14

    为什么复制构造函数被调用?

  15. 15

    std :: thread通过引用传递调用复制构造函数

  16. 16

    C ++:右值引用构造函数和复制删除

  17. 17

    引用具有禁用的复制构造函数/分配的对象

  18. 18

    std :: thread通过引用传递调用复制构造函数

  19. 19

    为什么在函数返回时不调用复制构造函数?

  20. 20

    为什么需要复制构造函数,何时在Java中使用复制构造函数

  21. 21

    为什么需要复制构造函数,何时在Java中使用复制构造函数

  22. 22

    javascript什么时候引用构造函数中使用的函数?

  23. 23

    javascript什么时候引用构造函数中使用的函数?

  24. 24

    复制构造函数

  25. 25

    强制复制构造函数

  26. 26

    复制构造函数

  27. 27

    意外的复制构造函数

  28. 28

    复制构造函数的参数

  29. 29

    复制构造函数

热门标签

归档