Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Use of deleted function when using fstream

I’m receiving the message "Use of deleted function" when I combine the use of an ofstream (which I later want to use to record information) and the placement of one class inside another. Here is my minimal example:

#include <iostream>
#include <unistd.h>
#include <fstream>

class Tracker {
    private:
        std::ofstream tracker_file;
    public:
        Tracker(const std::string filename) {
            tracker_file.open("tracker_file.csv", std::ios_base::app);
        }
};

class Penguin {
    private:
        Tracker p_tracker;
    public:
        Penguin(
            Tracker p_tracker
        ) : p_tracker(p_tracker) {}
};

int main()
{
    Tracker penguin_tracker = Tracker("output");
    Penguin gentoo(penguin_tracker);
    return 1;
}

I don’t understand how these are related, but if I remove the intermediate class then it works, and if I remove the ofstream it works.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

In this line in the ctor of Penguin:

) : p_tracker(p_tracker) {}

You attempt to initalize the Tracker p_tracker data member.
Since you pass it an existing Tracker instance, it attempts to use the copy constuctor.

But class Tracker does not have a copy constructor. This is the "deleted function" mentioned in the error you got.

The reason that the default copy constructor is not available is that you defined a custom constructor:

Tracker(const std::string filename) {...}

You could have can solved it by adding a copy ctor to Tracker, something like:

Tracker(Tracker const & other)
{
    // ...
}

However – class Tracker has a std::ofstream member which is non copyable.

So the question is what did you mean should happen in this case ?

On a side note: using the same name: p_tracker for both the class data member and the parameter passed to the constructor is a bit confusing and not recomended.

UPDATE:
To answer the question of the OP in the comment below:
If class Penguin only needs to keep a refernce to a Tracker instance, you can do the following (added "m_" prefix to members to diffrentiate them from other variables):

#include <iostream>
#include <fstream>

class Tracker {
// ... (no change)
};

class Penguin {
private:
    Tracker & m_tracker;
public:
    Penguin(
        Tracker & tracker
    ) : m_tracker(tracker) {}
};

int main()
{
    Tracker penguin_tracker("output");
    Penguin gentoo(penguin_tracker);
    return 0;
}

However – this solution requires you to ensure the Tracker penguin_tracker is alive as long as Tracker penguin_tracker is alive (otherwise you will have a dangling reference). In your example it is OK, just mentioned in for the general case.

Another side note: main should return 0 if all went well (not 1). See: What should main() return in C and C++?.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading