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.

>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++?.

Leave a Reply