Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Thinking in C++
Prev Contents / Index Next

const objects & member functions

Class member functions can be made const. What does this mean? To understand, you must first grasp the concept of const objects.

A const object is defined the same for a user-defined type as a built-in type. For example:

const int i = 1;
const blob b(2);

Here, b is a const object of type blob. Its constructor is called with an argument of two. For the compiler to enforce constness, it must ensure that no data members of the object are changed during the object’s lifetime. It can easily ensure that no public data is modified, but how is it to know which member functions will change the data and which ones are “safe” for a const object?

If you declare a member function const, you tell the compiler the function can be called for a const object. A member function that is not specifically declared const is treated as one that will modify data members in an object, and the compiler will not allow you to call it for a const object.

It doesn’t stop there, however. Just claiming a member function is const doesn’t guarantee it will act that way, so the compiler forces you to reiterate the const specification when defining the function. (The const becomes part of the function signature, so both the compiler and linker check for constness.) Then it enforces constness during the function definition by issuing an error message if you try to change any members of the object or call a non-const member function. Thus, any member function you declare const is guaranteed to behave that way in the definition.

To understand the syntax for declaring const member functions, first notice that preceding the function declaration with const means the return value is const, so that doesn’t produce the desired results. Instead, you must place the const specifier after the argument list. For example,

//: C08:ConstMember.cpp
class X {
  int i;
public:
  X(int ii);
  int f() const;
};

X::X(int ii) : i(ii) {}
int X::f() const { return i; }

int main() {
  X x1(10);
  const X x2(20);
  x1.f();
  x2.f();
} ///:~

Note that the const keyword must be repeated in the definition or the compiler sees it as a different function. Since f( ) is a const member function, if it attempts to change i in any way or to call another member function that is not const, the compiler flags it as an error.

You can see that a const member function is safe to call with both const and non-const objects. Thus, you could think of it as the most general form of a member function (and because of this, it is unfortunate that member functions do not automatically default to const). Any function that doesn’t modify member data should be declared as const, so it can be used with const objects.

Here’s an example that contrasts a const and non-const member function:

//: C08:Quoter.cpp
// Random quote selection
#include <iostream>
#include <cstdlib> // Random number generator
#include <ctime> // To seed random generator
using namespace std;

class Quoter {
  int lastquote;
public:
  Quoter();
  int lastQuote() const;
  const char* quote();
};

Quoter::Quoter(){
  lastquote = -1;
  srand(time(0)); // Seed random number generator
}

int Quoter::lastQuote() const {
  return lastquote;
}

const char* Quoter::quote() {
  static const char* quotes[] = {
    "Are we having fun yet?",
    "Doctors always know best",
    "Is it ... Atomic?",
    "Fear is obscene",
    "There is no scientific evidence "
    "to support the idea "
    "that life is serious",
    "Things that make us happy, make us wise",
  };
  const int qsize = sizeof quotes/sizeof *quotes;
  int qnum = rand() % qsize;
  while(lastquote >= 0 && qnum == lastquote)
    qnum = rand() % qsize;
  return quotes[lastquote = qnum];
}

int main() {
  Quoter q;
  const Quoter cq;
  cq.lastQuote(); // OK
//!  cq.quote(); // Not OK; non const function
  for(int i = 0; i < 20; i++)
    cout << q.quote() << endl;
} ///:~

Neither constructors nor destructors can be const member functions because they virtually always perform some modification on the object during initialization and cleanup. The quote( ) member function also cannot be const because it modifies the data member lastquote (see the return statement). However, lastQuote( ) makes no modifications, and so it can be const and can be safely called for the const object cq.

Thinking in C++
Prev Contents / Index Next

 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire