C++/scope

Advertisement


Question
QUESTION: Hi,

How are you? Thanks for taking questions. In my *.h file I have this class

class LargeFile {
int x;  
public:
void mergeFiles();
};

Why cannot I in my mergeFile() do this:

void mergeFiles()
{
x=5;
}

The compiler says that x was not defined in this scope. But why? The mergeFiles() is a member of class LargeFile, so why cannot I use its variables. Is it because I didn't specify the instance?

I'm actually trying to achieve this: define variables within a class so that all members of that class could directly and simply  use those variables. I don't want the class to do anything fancy. I don't want to give everything a global scope. How to do it properly? Thanks so much! Andres

ANSWER: Sorry but no, the declared and defined function mergeFiles is not a member of class LargeFile; mergeFiles is a non-member function declared (and defined) in the global namespace (i.e. the most outer, unnamed namespace, which can be accessed using a prefix :: to remove ambiguity where necessary: ::mergeFiles() ).

However the class LargeFile declares a member function mergeFiles and this is _in_ _the_ _namespace_ _of_ _the_ _class_, and so is fully named LargeFile::mergeFiles (or I suppose ::LargeFile::mergeFiles if you want to be really picky).

Hence to define class members outside of the class specification you have to qualify the member name with the class name:

   void LargeFile::mergeFiles()
   {
       x=5; // fully: this->x = 5;
   }

If you are still having a problem seeing why such qualification is required then consider the following example:

   class A
   {

   // ...

   public:
       void f();

   // ...

   };

   class B
   {

   // ...

   public:
       void f();

   // ...

   };

   // definition of a function called f
   void f() // is the definition of f a member of class A or class B or a free function?
   {

   // ...

   }

Such function definitions as for f in the example, as I pointed out initially, in C++ (and in this case C also) are members of no type - i.e. they are free functions. So how would we specify whether the definition of f were a free function, or the f member of class A or the f member of class B? Obviously some indication of which would be required - and as C++ added class members that required definition outside of the class specification beyond the existing C syntax - it was up to C++ to find some way to differentiate class member definitions from non-class definitions (as existed in C) and between different class member definitions that had the same member name. The syntax chosen is to prefix the class name and separate each part using ::. Note that classes can be nested in classes so you could end up with names like outer_class_name::inner_class_name::really_inner_class_name::member_name.

Since the original ISO C++ standard C++ has extended such name space qualifications to general namespaces which I shall leave to you to look up if you are interested, some links that might be useful are:

   http://www.cplusplus.com/doc/tutorial/namespaces/
   http://www.cprogramming.com/tutorial/namespaces.html
   http://www.tenouk.com/Module23.html

And some cautionary advice:

   http://www.gotw.ca/gotw/053.htm

And the general computer science concept of namespaces Wikipedia article:

   http://en.wikipedia.org/wiki/Namespace_(computer_science)


Hope this helps


---------- FOLLOW-UP ----------

QUESTION: Hi,

Thanks very much. However, when I make the change you suggested, the program won't compile. I get this error:

main.cpp: error: ‘mergeFiles’ was not declared in this scope

In my main.cpp I call the function simply like this:
mergeFiles();

Thanks for your continued help.
Andres

Answer
Err, maybe because the function is an _instance_ _member_ of a _class_ and so needs to be called on an _instance_ of that _class_.

Maybe you just forgot that when fixing the mergeFiles definition you then had to fix the code that calls it. Sorry I did not look beyond your question to manually check all your code for you - I really enjoy pretending to be the compiler for other people's code (not!) (or even my own code for that matter!!). That said sometimes I do pick up these other problems but not always - after all the compiler will pick them up for you - as you have found - and you should _not_ panic when it does - often its an "oops having changed that I forgot I now need to change this, this, this and this to suit...". We all get compiler (and sometimes linker) errors, get used to them and try to work out what they are on about.

Now if you had no class LargeFile, then you could have written mergeFiles as a stand alone function and call it as a stand alone function - but of course could not refer to any member of the (non-existent) LargeFile class, as you found previously.

However you define a class LargeFile with an x instance data member and a declared mergeFiles instance member function. You then insist on further using the name mergeFiles as if it were _not_ part of LargeFiles, except in the definition code body (from the first question) where you expected the compiler to magically know that it is part of LargeFile (and thereby that x is a member of LargeFile).

In brief you access a struct or union member in C or C++ and in C++ only a class member (C does not have classes) using the . (dot) operator:

   object_of_struct_union_or_class_type.member_of_that_type

You use the arrow operator to access members of an object from a pointer to that object:

   pointer_to_object_of_struct_union_or_class_type->member_of_that_type

(you can think of objects as variables).

You can declare and define such an object as for objects (variables) of built in types

   Typename objectname;  // Default initialisation

or

   Typename objectname( <initialisation argument list> ); // C++ syntax only

where:

   <initialisation argument list>

is a list of initialisation parameter value expressions as per a function call e.g.:

   arg1
   arg1, arg2,
   arg1, arg2, arg3
   1, 2
   "the name", 3, 4
   2.0*pi
   'a'
   collection.begin(), collection.end()

or:

   Typename objectname = initial_value_expression; // C-style object initialisation

(I am omitting brace initialisation: { v0, v1, v2, v3,...} here but you can look it up in any good C and C++ reference, plus it has changed for C++ in the latest 2011 standard - although most compilers do not yet support these new uses)

In this case you would create an object of type LargeFile using default initialisation as you define no explicit constructors for LargeFile so the only way to create a LargeFile object is to use the compiler supplied do-nothing default constructor:

   LargeFile lf;
   lf.mergeFiles();

If you are really confused by all this then I suggest you put down your development environment and go and read some good C++ reference material as you will continue to make such mistakes and become very confused. I do not have time to hand hold you through these fundamentals and doing it this way is something of a piecemeal, scattergun approach which will not help much with your overall understanding. It helps to learn at least the fundamental aspects of the usage you wish to make of a tool before you try to use it that way otherwise it might hurt you!

Many common C++ questions are answered on the C++ FAQ Lite site I reference in my instructions to questioners:

   http://www.parashift.com/c++-faq-lite/

However it is _not_ a language reference so you should use it in conjunction with a decent C++ tutorial and reference - I have no specific on line references in mind but the tutorial at the CPlusPlus site I pointed you to in my previous answer looks like it might be reasonable:

   http://www.cplusplus.com/doc/tutorial

You might like to download the whole thing as a PDF file (note the link at the top of the contents page).

In this case reading the parts on classes would seem good places to start.


Finally I present a list of some books on C++ and programming. They are aimed at absolute beginners through to experienced developers - so you certainly should not try them all at once!

For absolute beginners there are a couple of books:

"You Can Do It - A Beginner's Introduction to Computer Programming" by Francis Glassborow and Roberta Allen.

And the second book in the series:

"You Can Program in C++" by Francis Glassborow

People often recommend the following if you already have some programming experience:

"Accelerated C++" by Koenig and Moo

although I have not read any of these.

There are many books on programming in general that are good. I found

"The Practice of Programming" by Kernighan and Pike

to be particularly useful.

Also the man himself - Dr. Bjarne Stroustrup, the creator of C++ - has recently written a text book on learning to program (using C++ of course), "Programming -- Principles and Practice Using C++" (see http://www.research.att.com/~bs/programming.html). Note I have not read this one either.

For general good C++ usage you should look at

"Effective C++" "More Effective C++" and "Effective STL" by Scott Meyers

and the more advanced

"Exceptional C++" and "More Exceptional C++" and "Exceptional C++ Style" by Herb Sutter (See also http://www.gotw.ca/gotw/index.htm)
"Modern C++ Design" by Andrei Alexandrescu
"Ruminations on C++" by Koenig and Moo
"C++ Coding Standards" by Herb Sutter and Andrei Alexandrescu

For C++ reference you should look at:

"The C++ Programming Language" 3rd Ed. by Bjarne Stroustrup

the C++ reference book from the man himself. You should also take a look at his book "The Design and Evolution of C++".

In addition you will most likely find that a couple of additional reference works will be of use. For the standard C++ library there is:

"The C++ Standard Library - a Tutorial and Reference" by Nicolai M. Josuttis - it is one of my most referred to books.

And for C++ templates there is:

"C++ Templates the Complete Guide" by David Vandevoorde and Nicolai M. Josuttis.

For C reference I use the classic book "The C Programming Language" by Brian W. Kernighan and Dennis M. Ritchie. In fact this is quite a good book to learn C from if you have some programming experience already.

The final reference works I am going to recommend are the C++ and C standard documents themselves which are published in book form by Wiley or are available for download as a PDF from the ANSI web site for $30 US (price the last time I checked):

"Programming Languages - C++" and "Programming Languages - C"

the books are just titled:

"The C++ Standard" and "The C Standard"

These are _not_ easy reads, but are the word on how a C++ or C implementation should behave.

(note: there may have been recent updates to the ISO C and C++ standards documents from ANSI - the ISO 2011 C++ standard has been published and I think there may be a similar update to C that has or is about to also be published, so not sure if the afordable PDF editions are available yet - the books have not yet been updated)

These are just some of the books I have found (or read reviews that suggest they are) useful and are in no way a complete list. I suggest you try to find a real book shop (or maybe a library) that stocks at least some of these titles to see if any of them are for you. Alternatively you could look for reviews on the Internet. One good place for book reviews is the ACCU site at http://accu.org/, specifically http://accu.org/index.php?module=bookreviews&func=search (try entering C++ into the search box for example).

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.