You are here:

C++/c++ filehandling

Advertisement


Question
I want to initialise int value .but it gives error when i initialise it within class in public or privat heading. i wanna use this value in the function code which is declared as public and want to increament it after each function call. also i dont understand which variables should be private and which should be public.....plz help....i'm new to c++

Answer
First it is difficult to understand exactly what you are doing wrong without seeing exactly what it is you are doing. On the other hand just pasting all your code into your question and saying you have an error is also not very useful, so please do not do this either. What I need are the parts that are giving the error - a few lines to show what you tried and also what the errors were and which lines of code the errors refer to - compiler error messages give file names and line numbers, you can translate that into say a comment next to lines that had an error. e.g.:

   class Bad
   {
     int x = 3; // Error: 'Bad::x' : only static const integral data members can be initialized within a class
   };

The less code and the more obvious it is where the problem is the quicker it will be for me to see what is wrong and therefore start answering your question. Too much code, no hints etc. the harder it will be for me to find what is wrong - I may not have the time to sort out what is wrong and then formulate an answer so I may just reject the question.

Note that locating the lines errors refer to is made easier if you are using an integrated development environment (IDE) as usually you can step through compilation errors having the file and line number being made the current position for each one, e.g. by clicking on the error. Even if you are not using such and IDE most (all?) decent text editors can show  line numbers even if it is only in status information for the current location (by decent I mean better than the likes of Microsoft Window's Notepad!). Some editors also have the option of displaying line numbers to the left of the text. Apologies if you know this already but you say you are new to C++ so I do not know if you have familiarity with other programming languages and editors and so already have some knowledge of these things.

As I said I cannot from your question text discern exactly what it is you have done wrong nor exactly what you are trying to do, so I am going to have to guess. If I guess wrong and this is not what you are doing and/or not what you wish to know then I am sorry and please post another (possibly followup) question with more detailed information clarifying what you are doing, and wish to know and what problems you are having.

So my guess: You tried something like the above Bad class example to initialise a class instance data member and you would have received an error or errors similar to that shown in the comment. This is because class instance data members are _not_ variables. They are named data parts of objects (or instances or variables) of a user defined class type. Each such object of type Bad would acquire its own x data part.

The correct way to initialise per-object data is to define special class instance member functions called constructors. A constructor is a function that has the same name as the class and has _no_ return type specified. A class may have more than one constructor, allowing instances to be created in more than one way - that is with more than one set of parameters.

The compiler will provide certain constructors for you. It will provide what is known as a default constructor - one that takes no parameters if you do not define any other constructors explicitly. This will default construct each data member, which in the case of the built in types like int means it does nothing to initialise them (i.e. they are not initialised). A default constructor is used to create objects of a class when no parameters are specified, thus:

   SomeClass s; // s is an object of type SomeClass that is default constructed
   
Default constructors are also used to construct each object in a built in array of objects.

The other constructor that is automatically generated is a copy constructor, which is used to construct an object as a copy of an existing object of the same type:

   SomeClass s2 = s; // s2 copy constructed from s
   
Or in C++ initialisation style:

   SomeClass s2( s ); // s2 copy constructed from s

The compiler provided copy constructor will just do what is called a memberwise copy - each member is copied. If these are built in types (including pointers) then their values will just be copied to the new object. For data members of class types their copy constructors are called.

Unlike the default constructor a copy constructor is always provided by the compiler unless one is explicitly declared for the class in question.

Note that on a related note to copy constructors the compiler also generates an assignment operator (operator=) in a similar fashion to copy constructors that allows one object to be assigned to another:

   SomeClass s3; // s3 default constructed
   
   s3 = s2; // s2 value assigned to s3

So therefore what your class requires is at least an explicit default constructor:

   class Good
   {
       int x;

   public:
       Good()
       : x(3)
       {
       }
   };

This allows us to create Good objects without providing any parameters:

   Good g; // g is default constructed
   
Here I have not just declared a default constructor in the class definition but defined it as well. Like other member functions you can of course also provide the definition elsewhere in a related source implementation file (e.g. if class Good were defined in good.h then the implementation file might be called good.cpp):

   // In good.h:

   class Good
   {
       int x;

   public:
       Good();
   };


   // In good.cpp:
   
   #include "good.h" // for class Good definition
   
   // ...

   Good::Good()
   : x(3)
   {
   }

Notice some things about the form of a constructor definition. First, unlike other functions, be they members of a class or not, constructors can have a special section between the end of the declaration and before the opening brace of the function definition body, introduced using a colon ( : ), This section is called the initialiser list and occurs _only_ for constructor definitions. It consists of a list of class instance data members (and base classes) to be initialised. In this case there is only one data member and no base classes that require initialising, x. Note we _must_ use a constructor call style of initialisation here, you cannot use x = 3. If there were other data members then they could be initialised by separating each one by a comma:

   class Good
   {
       int x;
       int y;

   public:
       Good()
       : x(3), y(4)
       {
       }
   };

Also note that the order in which the data members are initialised is determined by their order of declaration in the class definition _not_ the order they appear in a constructor initialiser list, thus reversing the order of x and y initialisation in the Good constructor does not mean that y is initialised before x:

   class Good
   {
       int x;
       int y;

   public:
       Good()
       : y(4), x(3) // x still initialised before y as x declared before y in class definition.
       {
       }
   };

Some compilers will issue a warning about mismatches between member declaration order and constructor member initialisation order, for example the GNU g++ 4.1.2 compiler with the -Wall (warn all) option gave:

   main.cpp: In constructor ‘Good::Good()’:
   main.cpp:15: warning: ‘Good::y’ will be initialized after
   main.cpp:14: warning:   ‘int Good::x’
   main.cpp:18: warning:   when initialized here

We can place the warning text in comments for the lines referred to:

   class Good
   {
       int x;  //          ‘int Good::x’
       int y;  // warning: ‘Good::y’ will be initialized after

   public:
       Good()  // when initialized here
       : y(4), x(3)
       {
       }
   };

Base classes if they require other than default construction are initialised by placing a call to their required constructor in the initialiser list. They are initialised _before_ class data member initialisation and thus should be placed first in the initialiser list

   class Base
   {
       int baseValue;

   public:
       Base( int v )
       : baseValue( v )
       {
       }
   };

   class Good : public Base
   {
       int x;
       int y;

   public:
       Good()
       : Base(2), x(3), y(4)
       {
       }
   };

Do not worry if you have not come across derivation, base classes, derived classes etc. yet, I mention it for your information when you do.

The previous example shows a new class Base that has a constructor that takes an argument. Such constructors allow us to create objects that can be initialised from other data. Going back to the original simple Good class:

   class Good
   {
       int x;

   public:
       Good()
       : x(3)
       {
       }
   };

It would seem useful if Good objects could be initialised with an explicit value which can be used to initialise their x data members. As you have seen from Base this is simple to do, so we can add such a constructor thus:

   class Good
   {
       int x;

   public:
       Good()
       : x(3)
       {
       }

       Good( int v )
       : x(v)
       {
       }
   };

The new constructor takes a single int parameter v and uses it to initialise the x member. It allows us to create Good objects from an integer value thus:

   Good g(10); // g has its x member, g.x, initialised to the value 10

Note that Good has a copy constructor and assignment operator provided by the compiler which copies the value of x from one object to another:

   Good g1(10);  // g1.x initialised to 10
   Good g2(g1);  // g2 copy constructed from g1; g2.x = g1.x, thus g2.x == 10.
   Good g3;      // g3 default initialised; g3.x initialised to the value 3
   g3 = g2;      // g3 assigned the value of g2; g3.x = g2.x hence g3.x == 10
   
Ok so that answers, I hope, how to initialise an int instance class data member.

Next I am going to answer your last query:

In general _all_ data members should be private. This is because such details are implementation details of the class. If you need to modify or access the state provide public class instance member functions to do so.

Just because you are using an int today does not mean you may use one tomorrow. Maybe the information held by the simple int data member becomes more complex or is handled by another type and it has to be replaced with a class type data member. Those operations that just incremented or decremented or read the value of the old int value can now be forwarded to the equivalent operations of the replacement type. If your code accessed the int member directly then you would have to modify all the places where such access occurred - not a pleasant prospect in a large project!

So if you have an operation for objects of your class defined as a member function and you wish to access the data member just access it by name, thus (again I am not at all sure I am explaining what you want to know; if this is not what you want, sorry and please ask another question to clarify what you need to know):

   class Good
   {
       int x;

   public:
       Good()
       : x(3)
       {
       }

       Good( int v )
       : x(v)
       {
       }
       
       void Op()
       {
         ++x; // increment data member x
       }
   };

In reality you will probably wish to extract the value of the data member at some point. To do this provide a member function that returns the value of the data member. Here is a fuller example:

   class CountOperationCalls
   {
       int iCount;

   public:
       CountOperationCalls()
       : iCount(0)
       {
       }

       CountOperationCalls( int initialCount )
       : iCount(initialCount)
       {
       }

       void AnOperation()
       {
         std::cout << "AnOperation() called\n";
         ++iCount;  // increment call count
       }

       int GetOperationCallCount() const
       {
         return iCount;
       }
   };

CountOperationCalls can be used like so:

   int main()
   {
       int const MaxCalls( 10 );

       CountOperationCalls opCounter;

       while ( opCounter.GetOperationCallCount() < MaxCalls )
       {
         opCounter.AnOperation();
       }

       std::cout << "Operation call count = "
         << opCounter.GetOperationCallCount()
         << std::endl;
   }

You should of course include <iostream> to use std::cout (note: I assume ISO Standard C++). The output should look like:

   AnOperation() called
   AnOperation() called
   AnOperation() called
   AnOperation() called
   AnOperation() called
   AnOperation() called
   AnOperation() called
   AnOperation() called
   AnOperation() called
   AnOperation() called
   Operation call count = 10

The member functions AnOperation and GetOperationCallCount are instance member functions of the CountOperationCalls class. That is they know about the context of the object for whom they are called. This is done by having a pointer called 'this' associated with the function call (typically it is passed as a hidden parameter to the function call)
The this pointer of class instance member functions for a class X is of type X * or X const * if the member function is declared const, as in the case of CountOperationCalls::GetOperationCallCount. That is they are pointers to an object of X or to a constant object of type X (meaning the pointed to object cannot be modified). So CountOperationCalls::AnOperation has a this pointer of type CountOperationCalls * and CountOperationCalls::GetOperationCallCount has a this pointer of CountOperationCalls const *. The reason for specifying GetOperationCallCount const and making the this pointer a pointer to a constant CountOperationCalls is that it does not modify any of the object's state - it merely reads iCount to copy it to the return value (which is returned by value). Not specifying GetOperationCallCount const is not the end of the world but will prevent it from being used with constant objects of CountOperationCalls, whether such objects are constant to start with or made constant by being referred to by (C++) references or pointers to const.

The word 'this' is a keyword in C++. When we access an instance member in an instance member function, as in the use of iCount:

   class CountOperationCalls
   {

   // ...

       int GetOperationCallCount() const
       {
         return iCount;
       }
   };

it is shorthand for this->iCount:

   class CountOperationCalls
   {

   // ...

       int GetOperationCallCount() const
       {
         return this->iCount;
       }
   };

The value of the this pointer is the value of the address of the object associated with the member function call, thus in the line:

       opCounter.AnOperation();

the value of the this pointer in the call to CountOperationCalls::AnOperation() is &opCounter (where & here is the address of operator).

Hope this helps somewhat. Again, sorry if I have given you much information you did not want or need and if so then please do ask another question clarifying what it really is that you are trying to do, having problems with and need to know.  

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.