'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 1:[1]
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.
As @NathanPierson wrote in the comment below, this is because of the deleted copy constructor of the std::ofstream member variable tracker_file (and not because of the converting constructor you defined, as I originally wrote).
You could have theoretically solved it by adding a copy ctor to Tracker, something like:
Tracker(Tracker const & other)
{
// ...
}
However - as mentioned above 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>
// No change in Tracker:
class Tracker {
private:
std::ofstream m_tracker_file;
public:
Tracker(const std::string filename) {
m_tracker_file.open("tracker_file.csv", std::ios_base::app);
}
};
// Penguin now holds a reference to Tracker:
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++?.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
