Solved

Visual Studio Error C2248

Posted on 2012-04-10
13
950 Views
Last Modified: 2012-04-11
Greetings -- Please consider the following contentents of file TMDefinition.h, and how it might be leading to the intractible Error C2248 (described below) in Visual Studio.

----------------------------------------------------------------------

#include <iostream>
#include <fstream>
#include "StringVector.h"

using namespace std;

class TMDefinitionStream : public ifstream
{
private:
    StringVector keywords;
    string lastKeywordRead;
public:
    TMDefinitionStream(string fileName);        // This is the nexus of Error C2248
    bool Next_Word(string& toRead, bool& isKeyWord);
    string Last_Keyword_Read();      
};

----------------------------------------------------------------------------

Error   1   error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'  c:\users\gary\documents\visual studio 2010\projects\tmree\tmree\tmdefinitionstream.h      20      1      TMREe

----------------------------------------------------------------------------

1. This is the only error in the entire project.

2. By commenting out the several elements of the class definition, I find that the error seems to be centered on the constructor.  Without a constructor, the compiler complains about lots of OTHER things, but not C2248.  With the constructor, there will always be a C2248.  This is despite the fact that the error message itself points to line 20, which is the closing brace of the class definition.

3. The entire class definition is perfectly fine IN ITS CURRENT FORM if moved to main.cpp.  In that case, I had to alter the name of the class slightly, but that's all.  This leads me to think that perhaps something that *follows* TMDefinition.h is tripping it up.  That may be, but in the entire project TMDefinition.h is never the *last* header file called out.  I guess what I would be looking for here is if anyone can image what cockamamee thing might be in the next header file - that only comes up when this header file preceeds it - that would result in error E2248.

This project is an implementation of a Turing Machine for a college class I am taking.  One of the rules is that we can use no library other than the standard library.  Therefore, I cannot accept any solution that would violate that rule.  Beyond that, I started this as an "empty" project to make it as standard C++ as possible.  It will eventually have to be ported to a G++ compiler running on Ubuntu.

**** Many Thanks *****
0
Comment
Question by:NonComposMentis
  • 5
  • 4
  • 2
  • +1
13 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
What does 'StringVector.h' look like? The snippet you gave - with only small changes - compiles fine:

#include <iostream>
#include <fstream>
//#include "StringVector.h"

using namespace std;

class TMDefinitionStream : public ifstream
{
private:
    //StringVector keywords;
    string lastKeywordRead;
public:
    TMDefinitionStream(string fileName);        // This is the nexus of Error C2248
    bool Next_Word(string& toRead, bool& isKeyWord);
    string Last_Keyword_Read();      
};

Open in new window


All that VC++ 10 complains about the above is that 'main()' is missing (well, for sure), which makes me think that there is an issue with the aforementioned header file...
0
 

Author Comment

by:NonComposMentis
Comment Utility
Thanks, jkr:  here is StringVector.h

#ifndef StringVector_h
#define StringVector_h

#include <string>	// #include<string> must come before #include <vector>
#include <vector>

using namespace std;

class StringVector : public vector<string>
{
private:
	bool isCaseSensitive;

public:
	void Case_Sensitivity(bool isCaseSensitive);
	bool Is_In_Vector(const string& testString) const;
	bool Enqueue_Unique(const string& addString);
};

#endif

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Nope, no way, won't get the error with the above - not even a warning...
0
 

Author Comment

by:NonComposMentis
Comment Utility
Well, OK.  As I stated originally, I don't get the error either if I take the whole business and move it to main.cpp.  There is something about *where* it is or how it is used.  The compiler's message is not that helpful to me.  I was hoping perhaps someone else could decipher "cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'".
0
 
LVL 30

Accepted Solution

by:
Zoppo earned 500 total points
Comment Utility
Hi NonComposMentis,

I guess the problem is somewhere else in your code, I think the base class ifstream cannot be copied - do you anywhere create a copy of a TMDefinitionStream instance (can even be a function call where such an instance is passed by value instead of by reference). For any reason in this case VS 2010 shows an error in the class declaration without hint where the problem comes from.

I.e. take a look at this code:
class TMDefinitionStream  : public std::ifstream
{
public:
	TMDefinitionStream ( std::string fileName ) {}
};
TMDefinitionStream t1( "test.txt" );

Open in new window

This should compile fine - now add this line:
TMDefinitionStream t2( t1 );

Open in new window

Now VS 2010 reports the same error.

Hope that helps,

ZOPPO
0
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
... the same happens for code like
TMDefinitionStream t2 = t1;

Open in new window

or
void foo( TMDefinitionStream t2 ) {}
...
foo( t1 );

Open in new window

0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
... and, JFI, another possibility is returning a TMDefinitionStream - I once had the problem when I ported code from VC++ 6 to VS 2008, there was an overloaded shift operator like this:
class TMDefinitionStream  : public std::ifstream
{
public:
	TMDefinitionStream TMDefinitionStream::operator >> ( std::vector< std::string > v )	{ return *this; }
};

Open in new window

This compiled (and, at least how we used it, it worked) fine in VC++ 6, in VS 2010 I got the same error 2248 without any hint where the problem comes from (in a file with > 2000 lines).

In VS 2010 this has to be implemented like this:
class TMDefinitionStream  : public std::ifstream
{
public:
	TMDefinitionStream& TMDefinitionStream::operator >> ( std::vector< std::string > v )	{ return *this; } // return value must be a reference
};

Open in new window

ZOPPO
0
 

Author Closing Comment

by:NonComposMentis
Comment Utility
Just about every class in the project gets a turn at the "Turing machine definition stream", and yes, some of them were passed copies instead of references.  When I started this project I thought objects were *always* passed by reference.  Guess not in this language.  Many thanks!
0
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
Yes, in C/C++ values can be either passed by value or by reference (in C only possible with pointers) - i.e. take a look here about more info:
http://www.cplusplus.com/doc/tutorial/functions2/
http://en.wikipedia.org/wiki/Evaluation_strategy

Have a nice day,

best regards,

ZOPPO
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
>> using namespace std;

Unrelated to the problem but... having this in a header file is a really bad idea and just a problem waiting to happen. Trust me, you don't want to go polluting all your code with a namespace via a header file.
0
 

Author Comment

by:NonComposMentis
Comment Utility
So inside the header files, I just use "std::" everywhere?  I was kind of under the impression I had to use "using namespace std;" in each *file* that it was used in.  In other words, the header files would not "pollute" the cpp files, as you say.  But you're right.  I just tested it and calling out the namespace is unnecessary in the cpp file if it is done in the header.  That being the case, I can see the potential for conflicts.  Thanks!
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
>> So inside the header files, I just use "std::" everywhere?
Exactly.

>>  I was kind of under the impression I had to use "using namespace std;" in each *file*
Nope. Only where you want to import the namespace.

>>  In other words, the header files would not "pollute" the cpp files, as you say
They absolutely will and can result in some very hard to track down compiler time errors.

>> calling out the namespace is unnecessary in the cpp file if it is done in the header.
You should only have the using namespace clause in the .cpp file; NEVER the header.

"Namespace Rule #1: Avoid using directives entirely, especially in header files.

The reason for Rule #1 is that using directives cause wanton namespace pollution by bringing in potentially huge numbers of names, many (usually the vast majority) of which are unnecessary. The presence of the unnecessary names greatly increases the possibility of unintended name conflicts--not just in the header itself, but in every module that #includes the header. I find it helpful to think of a using directive as a marauding army of crazed barbarians that sows indiscriminate destruction wherever it passes--something that by its mere presence can cause "unintended conflicts," even when you think you're allied with it."

http://www.gotw.ca/publications/migrating_to_namespaces.htm

FWIW: GOTW is a very worthwhile read (it's quite large but full of very very helpful C++ tips).
0
 

Author Comment

by:NonComposMentis
Comment Utility
Thanks, evilrix.  I read the entire page you referenced.  I like that they show you how to do all the stuff they're trying to talk you out of!  Very nice.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now