Can't declare ifstream class member in header file - c++

I am trying to declare an ifstream object in a header file as is shown but I get an error saying that it cannot be accessed. I have tried various things such as making it into a pointer instead, initialising in the .c file etc. but my code can't seem to get part the declaration of it.
ReadFile.h:
#ifndef READFILE_H
#define READFILE_H
#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <fstream>
class ReadFile{
private:
std::ifstream stream;
public:
std::string read();
ReadFile(); // Default constructor
~ReadFile(); // Destructor
};
#endif
ReadFile.c:
#include "ReadFile.h"
ReadFile::ReadFile(){
stream.open("./data.txt");
}
ReadFile::~ReadFile(){
stream.close();
}
The error that I am getting is:
Error 9 error C2248: 'std::basic_ifstream<_Elem,_Traits>::basic_ifstream' : cannot access private member declared in class 'std::basic_ifstream<_Elem,_Traits>' c:\users\Bob\documents\project\models\readfile.h 23 1 Project
The output is:
1>c:\users\Bob\documents\project\models\readfile.h(23): error C2248: 'std::basic_ifstream<_Elem,_Traits>::basic_ifstream' : cannot access private member declared in class 'std::basic_ifstream<_Elem,_Traits>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\fstream(827) : see declaration of 'std::basic_ifstream<_Elem,_Traits>::basic_ifstream'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> This diagnostic occurred in the compiler generated function 'ReadFile::ReadFile(const ReadFile &)'
The error occurs when std::ifstream stream; is included and will disappear when this line is removed. What could be causing this error? Have I missed something really obvious or is there more to it?

The problem is that std::ifstream doesn't have a public copy constructor (because copying one wouldn't make sense) but the compiler-generated copy constructor for your class wants to use it.
It doesn't have any available assignment operator for the same reason (i.e. copying a std::ifstream is nonsense).
You should disallow copying and assignment for your class as well.
A simple way is to add
private:
ReadFile(const ReadFile&);
ReadFile& operator=(const ReadFile&);
to your class, if you're using C++03.
In C++11, use the = delete syntax.
public:
ReadFile(const ReadFile&) = delete;
ReadFile& operator=(const ReadFile&) = delete;

This isn't an answer per se, but in case anyone comes across this question in the future after struggling as much as I just have, I decided to post it anyway.
I was facing a very similar issue to the OP for basically the same reason, although the error message that Visual C++ was giving me was 'ClassName::ClassName(const ClassName &)': attempting to reference a deleted function. In my inexperienced mind, I was thinking "WTF, I'm not copying or assigning any copies anywhere!".
However, after an hour of screaming at the computer in frustration I was able to narrow the problem down to the ifstream class member, which led me here. And thanks to the accepted answer, I was able to narrow the problem down even further to this single line of code:
list.emplace_back(objParam);
Little did I know that std::vector objects need a copy constructor defined on their template parameter's type in order to reserve space for future emplace_back() calls and the like!
So the solution comes from this SO answer courtesy of Bryan Chen (emphasis added by me):
So you can see emplace_back does use the desired constructor to create the element and call copy constructor when it need to grow the storage. You can call reserve with enough capacity upfront to avoid the need to call copy constructor.
Full credit and many thanks go to Bryan and molbdnilo for leading me to this discovery.

Related

Troubles using fstream in a class

I get the following error, when compiling:
1>c:\users\ra\source\repos\sandbox\game\gamesetup_1\gamesetup_1\main.cpp(15): error C2280: 'DebugLib::DebugLib(const DebugLib &)': attempting to reference a deleted function
1>c:\users\ra\source\commonincludes\tannic\debuglib\debuglib.h(41): note: compiler has generated 'DebugLib::DebugLib' here
1>c:\users\ra\source\commonincludes\tannic\debuglib\debuglib.h(41): note: 'DebugLib::DebugLib(const DebugLib &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)'
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.16.27023\include\fstream(1421): note: 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)': function was explicitly deleted
1>Done building project "GameSetup_1.vcxproj" -- FAILED.
The code looks like this:
DebugLib.h:
#include <string>
#include <fstream>
class DebugLib
{
public:
DebugLib(); // Reset timestamp etc.
~DebugLib(); // Flush output buffer
void Init(uint8_t output, std::string fileName = "debug.log"); // Initializes Log
void Log(int category, std::string msg); // Add a line to the log
void Flush(); // Output the remains of the Debug buffer
void Shutdown(); // Shut it down
private:
unsigned int m_initTime;
unsigned int m_bufferPos;
std::string m_outputBuffer[DEBUG_MAXSIZE];
std::fstream m_fileStream;
uint8_t m_output;
bool m_running;
};
main.cpp:
#include <iostream>
#include <DebugLib.h>
using namespace std;
int main()
{
DebugLib gDebugger = DebugLib();
gDebugger.Init(DEBUG_LOG_TO_SCREEN);
cout << "Running!" << endl;
gDebugger.Shutdown();
cin.get();
return 0;
}
As soon as I declare m_fileStream I get the error. Do I have a wrong declaration ?
When I remove all the use of m_fileStream in DebugLib.cpp, the code compiles fine, and runs (but of course not as attended)
I couldn't find a duplicate even though I've seen this asked before, so:
Let's start by explaining the error messages. I'll ignore the line numbers and error codes, as those are rarely useful until after you've understood (or at least read) the rest of the error message.
'DebugLib::DebugLib(const DebugLib &)': attempting to reference a deleted function
This is the main error: an attempt to use a function that is deleted, namely the copy constructor for DebugLib. Since you did not explicitly specify a copy constructor, it is up to the compiler to define one for you. The compiler will define a naive copy if possible. If this definition is not possible, it will delete the copy constructor for you.
As you noticed, the compiler is able to define a naive copy until you add a field that cannot be copied (such as std::fstream).
note: compiler has generated 'DebugLib::DebugLib' here
This is a clarifying note that helps the error refer to two lines in your program. The line number that came with the main error message is where you tried to do the copy, and the line number that comes with this note is where the copy constructor is generated. The compiler is trying to be helpful because it doesn't know which location you'll want to change to address this error.
note: 'DebugLib::DebugLib(const DebugLib &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)'
This note explains the thing you noticed: copying your class is prevented because the std::fstream member cannot be copied. This message uses the name basic_fstream at this point, so it helps to know that fstream is an instantiation of the basic_fstream template. So that mess of code at the end of this note just names the copy constructor of std::fstream.
note: 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)': function was explicitly deleted
This is a further clarification. The line before this said "deleted or inaccessible". This line clarifies that to "explicitly deleted".
Now that we have read the error, we can go look at the lines to which it refers. The troublesome line is
DebugLib gDebugger = DebugLib();
This line requests that a DebugLib object be default constructed then copied to gDebugger. And there's the problem: it cannot be copied! The solution is to simplify your logic by removing the copy. You can invoked the default constructor directly on gDebugger. (This works for other constructors as well, should your code need them.)
DebugLib gDebugger{};
As a bonus, your code is shorter.

C++ Nvidia PhysX cannot convert PxFoundation to shared_ptr<>

Im trying to create a PxFoundation and save it in my member variable "foundation" which is a std::shared_ptr. However upon creating the object I get this:
C2440: '<function-style-cast>': cannot convert from 'physx::PxFoundation *' to 'std::shared_ptr<physx::PxFoundation>'
How can I put the raw pointer from the PxCreateFoundation function into a shared_ptr? as I'm not calling the ctor of any PhysX class I cannot use std::make_shared, so using the normal std::shared_ptr<>() constructor seems my only option?
Code:
#include <memory>
#include <PxPhysics.h>
#include "PhysXErrorCallback.hpp"
#include "PhysXDefaultAllocator.hpp"
#include <foundation/PxFoundationVersion.h>
class PhysicsEngine
{
public:
PhysicsEngine();
std::shared_ptr<physx::PxFoundation> foundation;
static PhysXErrorCallback gDefaultErrorCallback;
static PhysXDefaultAllocator gDefaultAllocatorCallback;
};
PhysicsEngine::PhysicsEngine()
{
foundation = std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback));
}
EDIT:
After chaning the
foundation = std::shared_ptr<physx::PxFoundation>(...)
to
foundation.reset(...)
it now gives me these errors:
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1519): error C2440: '<function-style-cast>': cannot convert from 'physx::PxFoundation *' to 'std::shared_ptr<physx::PxFoundation>'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1519): note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>physicsengine.cpp(25): note: see reference to function template instantiation 'void std::shared_ptr<physx::PxFoundation>::reset<physx::PxFoundation>(_Ux *)' being compiled
1> with
1> [
1> _Ux=physx::PxFoundation
1> ]
1>physicsengine.cpp(25): note: see reference to function template instantiation 'void std::shared_ptr<physx::PxFoundation>::reset<physx::PxFoundation>(_Ux *)' being compiled
1> with
1> [
1> _Ux=physx::PxFoundation
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1519): error C2228: left of '.swap' must have class/struct/union
EDIT2:
Heres the PxCreateFoundation declaration and definition:
PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation* PX_CALL_CONV
PxCreateFoundation(physx::PxU32 version, physx::PxAllocatorCallback& allocator, physx::PxErrorCallback& errorCallback);
physx::PxFoundation* PxCreateFoundation(physx::PxU32 version, physx::PxAllocatorCallback& allocator,
physx::PxErrorCallback& errorCallback)
{
return physx::shdfnd::Foundation::createInstance(version, errorCallback, allocator);
}
PxFoundation class:
/**
\brief Foundation SDK singleton class.
You need to have an instance of this class to instance the higher level SDKs.
*/
class PX_FOUNDATION_API PxFoundation
{
public:
virtual void release() = 0;
protected:
virtual ~PxFoundation()
{
}
};
createInstance definition:
Foundation* Foundation::createInstance(PxU32 version, PxErrorCallback& errc, PxAllocatorCallback& alloc)
{
//...
mInstance = reinterpret_cast<Foundation*>(alloc.allocate(sizeof(Foundation), "Foundation", __FILE__, __LINE__));
if(mInstance)
{
PX_PLACEMENT_NEW(mInstance, Foundation)(errc, alloc);
return mInstance;
}
//...
}
Seems like I found the error:
Most destructors in PhysX SDK are not public. Therefore trying to create a smart pointer with one of these classes results in an error.
Only other option beside using a raw pointer would be to create a custom deleter:
auto foundation = std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback), [=](physx::PxFoundation* f)
{
f->release();
});
Your foundation = line isn't actually calling a constructor. It's trying to cast the raw pointer to a shared_ptr using the syntax called a "functional cast" or "function-style cast" (#2 here), and then assign the result to the foundation variable (which has already been default-constructed). That won't work because shared_ptr has no cast from a raw pointer (to prevent it from accidentally taking ownership of things it shouldn't).
The best way to fix the problem is to use your constructor's initializer list to actually initialize foundation with the pointer:
PhysicsEngine::PhysicsEngine() :
foundation(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback))
{
// empty
}
This passes the pointer to foundation's constructor, as opposed to letting foundation be default-constructed and then assigning to it afterward in the constructor body. But if you really need to do it by assignment for some reason, you can use the reset function to tell foundation to take ownership of the pointer:
PhysicsEngine::PhysicsEngine()
{
foundation.reset(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback));
}

how to deal with a c++ related warning in boost option header file?

i have Microsoft Visual Studio (MSVS) 2012 Pro and i have set warning level to a slightly elevated level of 4. when doing this i am getting warnings for some of the included header files from the boost library. the message is this:
C:\Users\****\boost/optional/optional.hpp(595): warning C4244: 'initializing' : conversion from 'T_DOUBLE' to 'float', possible loss of data
C:\Users\****\boost/optional/optional.hpp(430) : see reference to function template instantiation 'void boost::optional_detail::optional_base<T>::construct<double>(Expr &&,const void *)' being compiled
with
[
T=T_FLOAT,
Expr=T_DOUBLE
]
C:\Users\****\boost/optional/optional.hpp(430) : see reference to function template instantiation 'void boost::optional_detail::optional_base<T>::construct<double>(Expr &&,const void *)' being compiled
with
[
T=T_FLOAT,
Expr=T_DOUBLE
]
the code in the file leading to this warning is this (line 610 on most recent beta of boost 1.64.0.B2 still resembles it exactly - but i am not on the beta now):
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Constructs using any expression implicitly convertible to the single argument
// of a one-argument T constructor.
// Converting constructions of optional<T> from optional<U> uses this function with
// 'Expr' being of type 'U' and relying on a converting constructor of T from U.
template<class Expr>
void construct ( Expr&& expr, void const* )
{
new (m_storage.address()) value_type(boost::forward<Expr>(expr)) ;
m_initialized = true ;
}
what is the reason (=learn to understand) for this warning and how to eliminate it in the boost header for me any anyone else? alternatively thinking: does it make sense to "fix" it in such a global way, or is there a deeper meaning pointing rather to somewhere else (either boost or application codes) to improve or fix those other codes?
You are probably passing a double literal into method that expects float. Something like foo(1.0) instead of foo(1.0f)

Passing CList variable gives error C2248: 'CObject::CObject' : cannot access private member

In My class, I've a static Clist variable declared in the following way:
#include<stdio.h>
#include<conio.h>
#include <afxtempl.h>
void otherfunc(CList<int,int> a)
{
}
class A
{
public:
CList<int,int> myvariable;
void myfunc()
{
otherfunc(myvariable);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a.myfunc();
getch();
return 0;
}
otherfunc() is not part of my class.
Where am I going wrong?
I have just pasted the code snippet with the problem. I have initiated it and everything works file except for the line where im calling otherfunc(). Its has no dependence over static keyword. Even if i remove static, i get the same error.
Edited : Here is the error tht I get :
C:\program files (x86)\microsoft visual studio 9.0\vc\atlmfc\include\afxtempl.h(776) : error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'
1> c:\program files (x86)\microsoft visual studio 9.0\vc\atlmfc\include\afx.h(561) : see declaration of 'CObject::CObject'
1> c:\program files (x86)\microsoft visual studio 9.0\vc\atlmfc\include\afx.h(532) : see declaration of 'CObject'
1> This diagnostic occurred in the compiler generated function 'CList<TYPE,ARG_TYPE>::CList(const CList<TYPE,ARG_TYPE> &)'
1> with
1> [
1> TYPE=int,
1> ARG_TYPE=int
1> ]
Your code as it is doesn't compile (Class should be class, Public should be public etc). What is the error message? Also you must post a simple compilable example that reproduce your error. My guess is that you didn't instantiate your static variable outside its class declaration, see
http://www.learncpp.com/cpp-tutorial/811-static-member-variables/
You may not get the error because of "Public:". Because "Public:" is not a key word it's a label. That's why "myvariable" is private by default.
Instead of "Public:" use "public:" and also replace "Static" with static.
Take a look at the definition of -
void otherfunc(CList<int,int> a)
The input parameter CList<int,int> a is passed by value, this means that when you call this function it will copy the input parameter by using CList<int,int> Copy Constructor.
But CList<int,int> does not implement a Copy Constructor, and its base class CObject define its Copy Constructor as private.
You should change the definition to -
void otherfunc(CList<int,int>& a)

Cannot make an object uncopyable

I'm making a server interface for network programming and I ran into a problem. I want to make a server object uncopyable, mostly because it doesn't really make sense to do so and would probably make problems, and also because it uses threads which can't be copied. However, when I make the copy constructor and assignment operator private, I get an error:
Error 2 error C2248: '(namespaces..)::Server::Server' : cannot access private member declared in class '(namespaces..)::Server' (path..)\type_traits 1545 1 Server
The error seems to be in the type_traits file? I haven't used it at all, though it might be possible that some of the other std files I'm including use it? I'm using iostream, sstream, string, thread, map.
Here's the server class definition:
class DLL_PUBLIC Server
{
public:
Server(unsigned int);
~Server();
(...)
private:
class PvtImpl; //Private implementation, so it isn't seen in the header file
PvtImpl *pvtImpl;
Server(const Server &par_other){}
Server& operator=(const Server &par_other){ return *this; }
(...)
};
and the private implementation:
class Server::PvtImpl
{
public:
bool running;
unsigned int port, backlog, currentlyConnected;
SOCKET listenSocket;
std::thread *acceptConnectionsThread;
std::thread* *receiveDataThreads; //I am using pointers instead of vectors because I want it to be fixed
ClientObj* *clients;
std::map<ClientObj*, unsigned int> clientIndexMap;
};
Since I don't know what code to post because I don't even know where the error is coming from, then tell me if you need a specific part of it posted. If I comment out the private copy constructor and assignment operator then it works, but I don't want this to be copyable and especially not through default constructor. Doubt it, but does it have something to do with it being a DLL?
Anyway that's it, thanks for your time
Update
So I added a = delete to the constructor as suggested, and also made it public:
class DLL_PUBLIC Server
{
public:
Server(unsigned int);
Server(const Server &par_other) = delete;
~Server();
Server& operator=(const Server &par_other) = delete;
(...)
};
I am getting a bit of a different error now, but also in the type_traits file:
Error 2 error C2280: '(namespaces..)::Server::Server(const (namespaces..)::Server &)' : attempting to reference a deleted function (path..)\type_traits 1545 1 Server
A bit of code it is complaining about in that file:
// TEMPLATE FUNCTION _Decay_copy
template<class _Ty> inline
typename decay<_Ty>::type _Decay_copy(_Ty&& _Arg)
{ // forward _Arg as value of decayed type
return (_STD forward<_Ty>(_Arg));
}
_STD_END
Update 2
So this is the output window from VS as requested:
1>(path...)\type_traits(1545): error C2280: '(namespaces..)::Server::Server(const (namespaces..)::Server &)' : attempting to reference a deleted function
1> (path..)\Server.h(19) : see declaration of '(namespaces..)::Server::Server'
1> (path..)\thread(47) : see reference to function template instantiation '(namespaces..)::Server std::_Decay_copy<(namespaces..)::Server&>(_Ty)' being compiled
1> with
1> [
1> _Ty=(namespaces..)::Server &
1> ]
1> Server.cpp(94) : see reference to function template instantiation 'std::thread::thread<void(__cdecl &)(const (namespaces..)::Server &),(namespaces..)::Server&>(_Fn,(namespaces..)::Server &)' being compiled
1> with
1> [
1> _Fn=void (__cdecl &)(const (namespaces..)::Server &)
1> ]
The line 19 in the Server.h it's mentioning is the copy constructor declaration. Line 94 in Server.cpp is thread creation:
pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, *this);
The acceptConnections function takes the server by constant reference so it shouldn't copy, here's the declaration:
friend void acceptConnections(const Server&);
Your problem is most likely in the thread constructor:
pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, *this);
Try this instead:
pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, std::ref(*this));
because without the std::ref() wrapper, a copy of your server instance will be passed into the thread constructor, which in turn will pass that copy by reference to your acceptConnections() method. Or at least try to, but it never got that far, as the compiler failed the initial copy.