Solved

Visual Studio Error C2248

Posted on 2012-04-10
13
961 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 2
  • +1
13 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 37828981
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
ID: 37829126
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
ID: 37829251
Nope, no way, won't get the error with the above - not even a warning...
0
Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

 

Author Comment

by:NonComposMentis
ID: 37829309
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 31

Accepted Solution

by:
Zoppo earned 500 total points
ID: 37829317
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 31

Expert Comment

by:Zoppo
ID: 37829342
... 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
 
LVL 31

Expert Comment

by:Zoppo
ID: 37829408
... 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
ID: 37829452
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 31

Expert Comment

by:Zoppo
ID: 37831285
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
ID: 37833039
>> 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
ID: 37833238
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
ID: 37833332
>> 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
ID: 37835795
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
c++ syntax question 9 58
Need more details 5 184
How to determine if the result of an equation is an integer in C++? 3 29
Can Live bindings change TGrid Cell Colour ? 1 35
When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

726 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