Friday, August 31, 2007

Web Services

0 comments;Click here for request info on this topic

Web Services are SOA enablers of choice. A web service is software designed to support interoperable machine-to-machine interaction over a network. Software applications written in the various programming languages and running on various platforms can use web services to exchange data over computer network like the internet in a manner similar to inter process communication on a single computer. This interoperability (e.g. between Java and python or windows and Linux application) due to the use of open standards. OASIS and W3C are the primary committees responsible for the architecture and standardization of web services. Web Services have an interface that is described in a machine-processable format like WSDL.

XML Web Services is a way to expose .Net classes across a TCP/IP network. It
uses a combination of SOAP, HTTP and XML, and is exposed via a web site
containing the services. The services are accessed via SOAP requests. It
enables the developer to create classes that can be used via web browser or
any other HTTP client application across the Internet. For a simple example,
you could create an XML Web Service Method that returns a .Net DataSet to
the client. The client could call the method, passing the various parameters
it takes, and get back a result set of data from over the Internet


What is WSDL?

The Web Services Description Language (WSDL) is an XML format published for describing Web Services. It is commonly abbreviated as WSDL in technical literature & often pronounced as “Whiz-Dull”. WSDL describes the public interface to the Web services. This is an XML based service description on how to communicate using the web service; namely the protocol bindings and message formats required to interact with web services listed in the directory. The supported operations and messages are described abstractly and then bound to a concrete network protocol and message format.

WSDL is often used in combination with SOAP and XML Schema to provide web service over the internet. A Client (program) connecting to a web service can read WSDL to determine what functions are available on the server. Any special data types used are embedded in the WSDL file in the XML Schema. The Client can then use SOAP to actually call one of the functions listed in WSDL.

What is UDDI?

UDDI is a acronym for Universal Description , Discovery and Integration - platform –independent , XML-based registry for business worldwide to list themselves on the Internet. UDDI is an open industry initiative enabling business to discover each other and define how they interact over the internet. A UDDI business registration consists of three components:

  1. White Pages – Address , contact and known identifiers;
  2. Yellow Pages – industrial categorizations based on standard taxonomies ; and
  3. Green Pages – technical information about services exposed by the business.



UDDI is nominally one of the core Web Services standards It is designed to be interrogated by SOAP messages and provide access to WSDL documents describing the protocol bindings and message formats required to interact with web services listed in its directory.


Seminar on Web Services:

Content:

Section 1:
Look Back,Whats wrong in previous Distributed models like DCOM,CORBA,RPC,RMI

Section 2:
Introduction,Defination,Example,Need for web services,Benefits, Key Features,Challenges faced By WS
Section 3:
SOAP,SOAP-XML Messaging Protocol,HTTP,XML,SOAP Header,WSDL,WSDL Elements ,WSDL header,UDDI,UDDI Components,

Section 4:
WebServices Platform,Web Services Security

Section 5:
WS for Java Developers,WS for .Net Developers

Section 6:
Web Services Application








Downloads Related Stuff:


Presentation Presentation

Synopsis

Report

The term Web services describes a standardized way of integrating Web-based applications using the XML, SOAP, WSDL and UDDI open standards over an Internet protocol backbone. XML is used to tag the data, SOAP is used to transfer the data, WSDL is used for describing the services available and UDDI is used for listing what services are available. Used primarily as a means for businesses to communicate with each other and with clients, Web services allow organizations to communicate data without intimate knowledge of each other's IT systems behind the firewall.
Unlike traditional client/server models, such as a Web server/Web page system, Web services do not provide the user with a GUI. Web services instead share business logic, data and processes through a programmatic interface across a network. The applications interface, not the users. Developers can then add the Web service to a GUI (such as a Web page or an executable program) to offer specific functionality to users.
Web services allow different applications from different sources to communicate with each other without time-consuming custom coding, and because all communication is in XML, Web services are not tied to any one operating system or programming language. For example, Java can talk with Perl, Windows applications can talk with UNIX applications.
Web services do not require the use of browsers or HTML.
Web services are sometimes called application services.
Read full story

XML

0 comments;Click here for request info on this topic
The XmlDocument class gives you the ability to load an Xml file. The class implements the DOM, which is an in-memory (cache) tree representation of an XML document, which allows you to navigate and edit the document.

The XmlDocument inherits from the XmlNode class, as seen in the class browser. The XmlNode class in reality provides much of the underlying functionality since it is the base class in the .NET implementation of the DOM.

So the XmlNode represents a single node in the Xml, while the XmlDocument extends the XmlNode class to represent an entire Xml Document (hence the name, XmlDocument).

Once the Xml file is loaded, you can also locate the root node of the document.

DOM

The W3C Document Object Model (DOM) is a platform and language neutral interface that allows programs and scripts to dynamically access and update the content, structure, and style of a document."

The W3C DOM provides a standard set of objects for representing HTML and XML documents, and a standard interface for accessing and manipulating them.

The DOM is separated into different parts (Core, XML, and HTML) and different levels (DOM Level 1/2/3):

Core DOM - defines a standard set of objects for any structured document
XML DOM - defines a standard set of objects for XML documents
HTML DOM - defines a standard set of objects for HTML documents

What is the XML DOM?
The XML DOM is the Document Object Model for XML
The XML DOM is platform and language independent
The XML DOM defines a standard set of objects for XML, and a standard way to access and manipulate XML documents
The XML DOM is a W3C standard.
The XML DOM views XML documents as a tree structure of elements embedded within other elements. All elements, their containing text and their attributes, can be accessed through the DOM tree. Their contents can be modified or deleted, and new elements can be created by the DOM. The elements, their text, and their attributes are all known as nodes.

The Document Object Model (DOM) class is an in-memory representation of an XML document. The DOM allows you to programmatically read, manipulate, and modify an XML document. The XmlReader class also reads XML, however it provides non-cached, forward-only, read-only access. This means that there are no capabilities to edit the values of an attribute or content of an element, or the ability to insert and remove nodes with the XmlReader. Editing is the primary function of the DOM. It is the common and structured way that XML data is represented in memory, although the actual XML data is stored in a linear fashion when in a file or coming in from another object. The following is XML data.

The XmlNode object is the basic object in the DOM tree. The XmlDocument class, which extends XmlNode, supports methods for performing operations on the document as a whole, for instance, loading it into memory or saving the XML to a file. In addition, XmlDocument provides a means to view and manipulate the nodes in the entire XML document. Both XmlNode and XmlDocument have performance and usability enhancements, and have methods and properties to:

Access and modify nodes specific to DOM, such as element nodes, entity reference nodes, and so on.
Retrieve entire nodes, in addition to the information the node contains, such as the text in an element node.
Read full story

Digital Coins

0 comments;Click here for request info on this topic
The Randomat idea for digital coins distinguishes itself by not relying on questionable encryption for the security of the mint. Security is hinged on the randomness of the identity of the bits -- using the Randomat bit language.

The Randomat based digital coin allows for a unique feature called
The Approval Tree. This feature allows for a distributed network for payment approval. It alleviates the dichotomy of either having no approval at all (relying on physical security), or having a single approval source, which tends to be overburdened.

Randomat digital coins can be readily combined and readily split --
by the traders themselves. It can be used to substitute for banking facilities (offering interest, and stock purchase), and Randomat digital coins offers a full range of anonymity while providing law enforcement with the tool to catch financial criminals.

This Randomat digital coin solution offers a robust answer to the
difficulties the plague the many alternatives that flood the market.

Digital Currencies

Electronic money - also known as digital currency - based on stored-value, smart card, or other technologies, have been developed to facilitate consumers and businesses to engage in global electronic commerce. Digital Currencies are cheaper, faster, safer, global, and more private than traditional credit cards and bank wires. This is the anonymous tax free easy access currency of the future. Non - tracable, no ID required, easy web based account access and has very low fees.
Read full story

Thursday, August 30, 2007

STL Algorithms

0 comments;Click here for request info on this topic

Special function objects allow us to override the default operator semantics of the generic algorithms

The range of elements over which the algorithm is to traverse is marked by a pair of iterators: a first iterator that addresses the first element to operate upon and a last iterator that marks 1 past the last element to operate upon. The element addressed by last is not itself operated upon; it serves as a sentinel to terminate the traversal. It also serves as the return value indicating no position. If the value is found, the iterator marking that position is returned.

Two versions of each algorithm: one that uses the equality operator of the underlying type of the element, and one that uses a function object or pointer to a function to implement the comparison.

Five categories of iterators predefined by the standard library.

A ForwardIterator supports both reading and writing of the element it addresses.

int *presult = find( &ia[0], &ia[6], search_value );

cout "The value " search_value( presult == &ia[6] ? " is not present" : " is present" )endl;

If the pointer returned is equal to the address of &ia[6] (that is, 1 past the elements of ia), then the search is unsuccessful; otherwise, the value is found.

The copy() algorithm takes as its first two arguments a pair of iterators marking the range of elements to be copied. The third argument is an iterator marking where to begin placing the elements copied. back_inserter is spoken of as an iterator adaptor; it causes elements to be inserted at the back of the vector passed to it as an argument.

unique() removes duplicate values from the container, but only those duplicate values that are adjacent. Given the sequence 01123211, the result is 012321 and not 0123. To achieve the latter result, we must first sort() the vector; that is, the sequence 01111223 becomes 0123. Well, almost. Actually, the result is 01231223.

unique() behaves somewhat unintuitively: the size of the container it acts upon is not changed. Rather, each unique element is assigned in turn to the next free slot beginning with the first. In our example, the physical result is 01231223; the sequence 1223 represents, so to speak, the refuse of the algorithm. unique() returns an iterator marking the beginning of this refuse. Typically, this iterator is then passed to the associated erase() container operation to delete the invalid elements. (Because the built-in array does not support an erase() operation, the family of unique() algorithms is less suited to the built-in array type.) Here is this portion of our function:

void process_vocab( vector<>*pvec )

{

// ...

// sort the elements of texts

sort( texts.begin(), texts.end() );

// delete all duplicate elements

vector::iterator it;

it = unique( texts.begin(), texts.end() );

texts.erase( it, texts.end() );

// ...

}



stable_sort() preserves the relative position of equivalent elements; within elements of the same length, the current alphabetical ordering is maintained.

remove() behaves the same as unique() in that it does not actually alter the size of the container but rather separates the elements into those to be retained (copying them in turn to the front of the container) and those to be removed (which remain at the back). It returns an iterator marking the first element of those to be removed. Here is how we might use it to erase a collection of common words we do not wish to retain within the vector:

void process_vocab( vector<>*pvec )

{

// ...

static string rw[] = { "and", "if", "or", "but", "the" };

vector<> remove_words( rw, rw+5 );

vector::iterator it2 = remove_words.begin();

for ( ; it2 != remove_words.end(); ++it2 ) {

// just to show another form of count()

int cnt = count( texts.begin(), texts.end(), *it2 );

cout cnt " instances removed: " (*it2) endl;

texts.erase( remove(texts.begin(),texts.end(),*it2 ) texts.end()

);

}

}

IMP

bool less_than( const string & s1, const string & s2 )

{

return s1.size() <>

}

void process_vocab( vector<>*pvec )

{

// ...

// sort the elements of texts by length

// preserving the previous order of elements

stable_sort( texts.begin(), texts.end(), less_than );

// ...

}


Although this gets the job done, it is considerably less efficient than we might wish.
less_than() is implemented as a single statement. Normally, it would be invoked as an inline function. By passing it in as a pointer to function, however, we prevent it from being inlined.

An alternative strategy to preserve the inlineability of the operation is the use of a function object.


The benefits of a function object over a pointer to function.

First, if the overloaded call operator is an inline function, the compiler is able to perform the inlining, providing a possibly significant efficiency gain.

Second, the function object can hold an arbitrary amount of additional data, either cached results or data to help in the current operation.

Three sources of function objects.

􀁺 A set of arithmetic, relational, and logical function objects is predefined by the standard library.

􀁺 A set of predefined function adaptors allows us to specialize or extend the predefined function objects (or, for that matter, any function object).

􀁺 We can define our own function objects, to be passed to the generic algorithms and possibly against which to apply the function adaptors.

Function Adaptors for Function Objects

The standard library also provides a set of function adaptors with which to specialize and extend both unary and binary function objects. The adaptors are special classes divided into the following two categories.

  1. Binders: a binder is a function adaptor that converts a binary function object into a unary object by binding one of the arguments to a particular value. For example, to count all the elements within a container that are less than or equal to 10, we would pass count_if() a less_equal function object with one of its arguments bound to 10. In the following section we'll look at how we do that.

2. Negators: a negator is a function adaptor that reverses the truth value of a function object. For example, to count all the elements within a container that are greater than 10, we could pass count_if() the negator of our less_equal function object with one of its arguments bound to 10. Of course, in this case, it is considerably more straightforward to simply pass a binder of the greater function object with one of its arguments bound to 10.

There are two predefined binder adaptors provided by the standard library: bind1st and bind2nd.

bind1st binds the value to the first argument of the binary function object, and

bind2nd binds the value to the second

Read full story

STL Introduction

0 comments;Click here for request info on this topic

Iterators are an abstraction of pointers. They provide a means to traverse containers and access objects within containers.

The generic algorithms are a collection of routines that can be used to perform common operations on container classes, such as sorting, merging and finding. The are called generic because they are independent of the container class used and of the datatype of the objects held in those container classes. The iterators are used to link a container with an algorithm. A container class has methods to return iterators that provide access to its contents. These iterators are provided, as arguments, to an algorithm. The algorithm can then traverse, access and manipulate the contents of the container.

There are a few benefits that the container classes offer over arrays.

  • Container classes handle all sizing and memory allocation issues. You can't write past the end of a container class like you can with an array
  • Container classes are optimized for their intended use. Some allow constant time insertions at their end, some allow this anywhere. Some are better to maintain sorted lists, some better for random access retrievals. We'll learn more on this as we proceed.
  • They contain utility methods such as empty(), size() and clear() that can simplify programming.
  • They contain other methods that all insertion, deletion and copying.
  • They have equality, inequality and assignment operators. You can directly compare two containers or assign on to another.
  • They provide iterators. Iterators are an abstraction of pointers. They allow similar syntax and use, but also have some built-in methods and checks that increase their utility.

The Big-Oh

Before we begin to discuss containers further and begin to discuss the other important components of the STL, such as the generic algorithms, it is necessary to understand a little about quantifying computational costs. We need a measure to understand how an algorithm behaves. Suppose, we run an algorithm on a container containing 5 objects during testing and now we intend to run this algorithm on a container containing 50, 500 or 5 million objects. How long will it take? How do we quantify this? Suppose, we retrieve the first element in a container. How long does it take to retrieve the 79th? The same amount of time? Seventy-nine times as much time? The answers to these questions depend on the particular container or particular algorithm, but there are standard ways of expressing and quantifying these relationships. The computational cost of an algorithm or operation is generally expressed using big-Oh notation. I'm sorry to disappoint any of my readers about the sub-title. The "Oh" indicates the order of the operation. It may be constant, or increase in some other way as the size of the container or number of elements being manipulated increase. The "big" in "big-Oh" indications that we are interest in approximate or order of magnitude estimates. If it takes twice as long to retreive element 79 as element 1, this is still considered a constant time. That's close enough. We're concerned that the retrieval time does not increase quadratically (as a square or power of 2) or cubically (power of 3) for instance. If that were the case the operation would require on order of 79^2 = 6241 or 79^3 = 493039 times the number of operations as the retrieval of element 1.

  • Constant time, O(1). The cost of the operation is independent of the size of the container or number of elements. As noted above, it may not really be constant, but to a resonable approreasonable it's constant.
  • Linear time, O(N). The cost of the algorithm or operation increases linearly as the number of elements increases. For example, the cost to retrieve element 79 is roughly 79 times the cost to get element 1.
  • Quadratic time, O(N2). The cost of the algorithm or operation increases as the square of the number of elements. This is the case for some crude sorting algorithms.
  • Logarithmic time, O(log N). The cost of the algorithm or operation increases as the log of the number of elements. As a review, logbasenumber = exponent. For example, log10100 = 2 and log1000 = 3. For decimal numbers, logs are often written without explicitly showing the base. For instance, log10X is usually written as log X. You should note that for many algorithms that work by successively dividing the number of elements in half, such as many tree based algorithms, the cost actually increases as log2 N. The cost, however, is usually expressed as O(log N) = O(log10N). Why, because logarithms in different bases of the same number are related by a constant. For now, just remember that operations that increase logarithmically increase more slowly than those that increase linearly.
  • O(N log N). The cost increases on the order of N log N. This is true for some algorithms. For instance, the Fast Fourier Transform, FFT, beloved by electrical engineers world wide, has this property.

How do all these orders relate to each other? Let's look at some examples

Number of elements

O(1)

O(log N)

O(N)

O(N log N)

O(N2)

10

constant

1

10

10

100

100

constant

2

100

200

10000

1000

constant

3

1000

3000

1000000

10000

constant

4

10000

40000

100000000

As you can see, as the number of elements increases, the order of an algorithm becomes very significant.

Sequence Containers

The STL provides both sequence and associative containers. The sequence containers are meant to hold a collection of objects of one type in a linear sequence. This is similar to an array. The STL provides three sequence containers.

  • vector - The vector class provides random access retrievals of objects at any position in constant time. This is useful if your code needs to access elements in an unordered way. You need element 1, then element 5, then element 8752 and so on. The cost (cpu clocks or time needed) of getting element 8752 can be considered to be the same constant as the cost to retreive element 1, for instance. Vector is optimized for insertions and deletions at its end. These are also done in constant time. Insertions or deletions at positions other than the end require linear time.
  • deque - The deque (pronounces deck) class also provides random access retrievals of objects at any position in constant time. Insertions and deletions at both the front and end of a deque are optimized and occur in constant time. Insertions and deletions in the middle require linear time.
  • list - The list class does not support random access retrievals. Retrievals require linear time. This is because lists are implement with an underlying doubly linked-list structure. A linked-list is a series of nodes connected by previous and next pointers. The "previous" pointer gets you to the previous element; the next pointer to the next. Insertions and deletions at any point are efficient and occur in constant time. Insertion or deletion requires onlreassignmentnt of the next and previous pointers. No elements must be moved. Insertions and deletions in the middle of vectors and lists and at the beginning of vectors require other elements to be moved. This is why they require linear time.

In addition to the containers list above, ordinary arrays and the string class can be considered sequence containers. As will be shown later, they can also be used with the generic algorithms that provide much of the usefulness of the STL. In addition, most STL implementations also provide stack, queue and priority queue container classes. These classes are created using container adapters and one of the core STL sequence containers. We explore this in a later lesson.

Generic Algorithms

The generic algorithms provide functions that implement many common programming tasks in efficient manners. We'll explore these algorithms in detail later in the tutorial. For now, I'll just list them so that you can see the wide range of algorithms available. Many of the algorithms have overloaded function signatures. That is, they have versions that take different number and/or types of arguments. Here is a list of the algorithms. You can surmise their use from their names. The suffix "if" on some of the method names indicates that the method takes a function object as an argument. We'll see more on this shortly. The suffix "copy" indicates that the method copies its results into a destination container.

adjacent_find

binary_search

copy

copy_backward

count

count_if

equal

equal_range

fill

fill_n

find

find_end

find_first_of

find_if

for_each

generate

generate_n

includes

inplace_merge

iter_swap

lexicographical_compare

lower_bound

make_heap

max

max_element

merge

min

min_element

mismatch

next_permutation

nth_element

partial_sort

partition

pop_heap

prev_permutation

push_heap

random_shuffle

remove

remove_copy

remove_copy_if

replace

replace_copy

replace_copy_if

replace_if

reverse

reverse_copy

rotate

rotate_copy

search

search_n

set_difference

set_intersection

set_symmetric_difference

set_union

sort

sort_heap

stable_partition

stable_sort

swap

swap_ranges

transform

unique

unique_copy

upper_bound

The point to take away is that there are many algorithms available and that before writting code, check to see if an existing algorithm can suffice.

Function Objects

Many of the generic algorithms on the previous page perform some type of comparison or test as they execute. For instance, the count function returns the number of elements equal to some value. The find function returns an iterator containing the location of the first element equal to some value. If this were the limit to the flexibility of these algorithms they would still be useful, but the STL was designed to make the algorithms significantly more flexible and more useful. Many of the algorithms have versions that take a function or function object as an parameter. Function objects are classes that have the function operator, (), overloaded. These function or function objects usually take one or two parameters and return a boolean, or true/false value. A function that returns a boolean value is also called a predicate. Let's see how a predicate can be used to extend the functionality of the count algorithm.

#include
#include
#include
using namespace std;

bool less (const int i) {
return i < 25;
}

bool more (const int i) {
return i > 25;
}

int main( )
{

// Creates an empty vector
vector v1;

// Add numbers to vector
v1.push_back(12);
v1.push_back(25);
v1.push_back(25);
v1.push_back(35);
v1.push_back(45);

// Finds the number of elements equal to 25
int quantity = count(v1.begin(), v1.end(), 25);

cout << quantity << " elements equal to 25" << endl;

// Finds the number of elements less than 25
quantity = count_if(v1.begin(), v1.end(), less);

cout << quantity << " elements less than 25" << endl;

// Finds the number of elements greater than 25
quantity = count_if(v1.begin(), v1.end(), more);

cout << quantity << " elements greater than 25" << endl;

return 0;
}

OUTPUT:
2 elements equal to 25
1 elements less than 25
2 elements greater than 23

Notice how the behavior of count is modified when a predicate, such as the functions less or more, is provided as a parameter. Instead of a simple function as shown in this example, a class that overloads the function operator, (), could also be used. We will see the benefits of this in a later lesson. Also, please note that the STL provides built-in function objects via the functional include file. This will be covered in a later lesson

Adapters

The last piece of the STL to be introduced in this overview are adapters. Adapters modify the interface or the behavior of other STL components. Adapters can be used to modify iterators, containers or function objects. For example, an iterator can be modified into a reverse iterator that traverses a container in the opposite direction. A vector can be modified into a stack using a container adapter. The behavior and interface of function objects can be changed by function adapters. Let's redo the last example using two binary predicates that are part of the STL, less and greater. Less compares two values and returns true if the first is less than the second. Greater returns true is the second is greater than the first. On the last page we counted values in a vector less that 25 and greater than 25. We want to use these predicates with the "second" value hard coded to 25. To do this using the STL provided less and greater function objects we need to use an adapter, bind2nd, that binds the second value in these function objects to 25. For now, you only need to see how adapters can greatly extend the usefulness of other STL components. We'll handle all the details in later lessons.

#include
#include
#include
#include
using namespace std;

int main( )
{

// Creates an empty vector
vector v1;

// Add numbers to vector
v1.push_back(12);
v1.push_back(25);
v1.push_back(25);
v1.push_back(35);
v1.push_back(45);

// Finds the number of elements equal to 25
int quantity = count(v1.begin(), v1.end(), 25);

cout << quantity << " elements equal to 25" << endl;

// Finds the number of elements less than 25
quantity = count_if(v1.begin(), v1.end(), bind2nd(less(),25));

cout << quantity << " elements less than 25" << endl;

// Finds the number of elements greater than 25
quantity = count_if(v1.begin(), v1.end(), bind2nd(greater(),25));

cout << quantity << " elements greater than 25" << endl;

return 0;
}

OUTPUT:
2 elements equal to 25
1 elements less than 25
2 elements greater than 23

Read full story

Wednesday, August 29, 2007

Mixing Overloading with Inheritance

0 comments;Click here for request info on this topic

What is the difference between overloaded functions and overridden functions?

Overloading has the same scope, same name, different signatures, and virtual is not required. Overriding has different scopes, same name, same signatures, and virtual is required.

The term signature designates the combination of a function's name, the types and order of its parameters, and, if the function is a nonstatic member function, its const and/or volatile qualifiers.

Overloading occurs when two or more functions are in the same scope (for example, both in the same class or both at namespace scope) and have the same name but different signatures. Overriding occurs when a class and one of its derived classes both define a member function with the same signature and the member function is declared to be virtual in the base class.

In the following example, Base::f(int) and Base::f(float) overload each other, while Derived::g() overrides Base::g().

#include 
using namespace std;
class Base {
public:
  virtual ~Base()         throw();
  virtual void f(int x)   throw();
  virtual void f(float x) throw();
  virtual void g()        throw();
};
 
Base::~Base() throw()
  { }
void Base::f(int x) throw()
  { cout << "Base::f(int)\n"; }
void Base::f(float x) throw()
  { cout << "Base::f(float)\n"; }
void Base::g() throw()
  { cout << "Base::g()\n"; }
 
class Derived : public Base {
public:
  virtual void g() throw();
};
 
void Derived::g() throw()
  { cout << "Derived::g()\n"; }
 
int main()
{
  Derived d;
  Base* bp = &d;  // OK: Derived is kind-of Base
  bp->f(42);
  bp->f(3.14f);
  bp->g();
}

The output of this program follows.

Base::f(int)
Base::f(float)
Derived::g()

FAQ 29.02 What is the hiding rule?

A rule in C++ that tends to confuse new C++ developers.

The hiding rule says that an entity in an inner scope hides things with the same name in an outer scope. And since a class is a scope, this means that a member of a derived class hides a member of a base class that has the same name as the derived class member. Confused? Don't give up; this is really important stuff.

There are two common situations when the hiding rule confuses people. First, when a base class and a derived class declare member functions with different signatures but with the same name, then the base class member function is hidden. Second, when a base class declares a nonvirtual member function and a derived class declares a member function with the same signature, then the base class member function is hidden (technically the same thing happens with virtual member functions, but in that case it hardly ever confuses people).

In the following example, Base::f(float) and Base::g(float) are virtual and therefore can be overridden by derived classes, but Base::h(float) is nonvirtual and therefore should not be redefined in derived classes.

#include 
using namespace std;
 
class Base {
public:
  virtual ~Base()         throw();
  virtual void f(float x) throw();
  virtual void g(float x) throw();
          void h(float x) throw();
};
 
Base::~Base() throw()
  { }
void Base::f(float x) throw()
  { cout << "Base::f(float)\n"; }
void Base::g(float x) throw()
  { cout << "Base::g(float)\n"; }
void Base::h(float x) throw()
  { cout << "Base::h(float)\n"; }

In the following code, member function Derived::f(float) is a normal override of virtual Base::f(float). However, Derived::g(int) hides (rather than overrides or overloads) Base::g(float) and Derived::h(float) hides (rather than overrides or overloads) Base::h(float).

class Derived : public Base {
public:
  virtual void f(float x) throw();                   <-- 1
  virtual void g(int x)   throw();                   <-- 2
          void h(float x) throw();                   <-- 3
};
void Derived::f(float x) throw()
  { cout << "Derived::f(float)\n"; }
void Derived::g(int x) throw()
  { cout << "Derived::g(int)\n"; }
void Derived::h(float x) throw()
  { cout << "Derived::h(float)\n"; }

(1) Good: Overrides Base::f(float)

(2) Bad: Hides Base::g(float)

(3) Bad: Redefines a nonvirtual function

Because Derived::f(float) is a normal override of Base::f(float), calling f(3.14f) on a Derived object does the same thing independent of whether the reference to the Derived object is of type Base& or type Derived&. Said simply, the behavior depends on the type of the object, not on the type of the reference. This is the normal (and desirable) effect of dynamic binding, and it is shown in sampleOne().

void sampleOne(Base& b, Derived& d)
{
  b.f(3.14f);                                        <-- 1
  d.f(3.14f);
}
 
int main()
{
  Derived d;
  sampleOne(d, d);
}

(1) Good: If the object is a Derived, calls Derived::f(float)

Unfortunately, Derived::g(int) neither overrides nor overloads Base:: g(float) but rather hides Base::g(float). Therefore the compiler calls g(float) if someone tries to call g(int) on a Derived&. This behavior is surprising to many developers; it is shown in sampleTwo().

void sampleTwo(Base& b, Derived& d)
{
  b.g(3.14f);
  d.g(3.14f);                                        <-- 1
}
 
int main()
{
  Derived d;
  sampleTwo(d, d);
}

(1) Bad: Converts 3.14 to 3 and calls Derived::g(int)

Also unfortunately, Derived::h(float) is a redefinition of the nonvirtual function Base::h(float). Since Base::h(float) is nonvirtual, Derived:: h(float) is not an override, and dynamic binding does not occur. Therefore, the compiler calls Base::h(float) if someone tries to call h(float) on a Derived object using a Base&. This behavior is surprising to many developers; it is shown in sampleThree().

void sampleThree(Base& b, Derived& d)
{
  b.h(3.14f);                                        <-- 1
  d.h(3.14f);
}
 
int main()
{
  Derived d;
  sampleThree(d, d);
}

(1) Bad: Calls Base::h(float)—does not use dynamic binding

The root problem with sampleTwo() and sampleThree() is that the behavior depends on the type of the reference rather than on the type of the object. For example, in sampleThree() the member function that gets invoked is the one associated with the reference's type, not the one associated with the object's type. These behaviors surprise users, since users normally expect behavior to depend on the type of the object rather than on the type of the reference or pointer used to access that object.

The hiding rule may not seem intuitive, but it prevents worse errors, especially in the case of assignment operators. If, for example, the hiding rule were removed, it would be legal to assign a Circle with a Square (the Shape part of the Square would be copied into the Shape part of the Circle).

FAQ 29.03 How should the hiding rule be handled?

Avoid triggering the hiding rule when possible, and use the following work-arounds when the hiding rule can't be avoided.

Avoid hiding inherited public: member functions whenever possible. When it cannot be avoided, it is important not to surprise the class's users. The guiding principle is to avoid confusing users: when a Base* can be used to call a member function on a Derived object, calling it via a Derived* shouldn't alter the observable behavior.

In the case of redefining a nonvirtual member function, as in Base::h(float) from the previous FAQ, the simplest way to avoid surprising users is to use the virtual keyword when declaring the base class member function. In those rare cases where the base class function cannot be virtual, ensure that the observable behavior of the derived class function is identical to that of the base class.

For example, an experienced C++ programmer might use a nonvirtual member function to avoid the (small) overhead of a virtual function call, yet might also redefine that member function in a derived class to make better use of the derived class's resources. To avoid surprising users, there must not be any differences in the observable behavior of the two functions. Note: These relationships are somewhat subtle; if the code will be maintained by less experienced programmers, a normal, virtual function is probably a better choice.

In the case where a base class and a derived class declare member functions with the same name but different signatures, as in Base::g(float) and Derived::g(int) in the previous FAQ, a using declaration (FAQ 29.04) should be employed.

The following shows how these guidelines can be applied to the example from the previous FAQ.

#include 
using namespace std;
 
class Base {
public:
  virtual ~Base()         throw();
  virtual void f(float x) throw();
  virtual void g(float x) throw();
  virtual void h(float x) throw();
};
 
Base::~Base() throw()
  { }
void Base::f(float x) throw()
  { cout << "Base::f(float)\n"; }
void Base::g(float x) throw()
  { cout << "Base::g(float)\n"; }
void Base::h(float x) throw()
  { cout << "Base::h(float)\n"; }
 
class Derived : public Base {
public:
  virtual void f(float x) throw();
  virtual void g(int x)   throw();                   <-- 1
  using Base::g;                                     <-- 2
};
 
void Derived::f(float x) throw()
  { cout << "Derived::f(float)\n"; }
void Derived::g(int x) throw()
  { cout << "Derived::g(int)\n"; }

(1) Normally this would hide g(float) (bad!)

(2) But this line unhides g(float) (good!)

After applying these fixes, users are not confused because the behavior depends on the type of the object rather than on the type of the pointer used to access that object.

void sample(Base& b, Derived& d)
{
  b.f(3.14f);
  d.f(3.14f);
 
  b.g(3.14f);
  d.g(3.14f);                                        <-- 1
 
  b.h(3.14f);
  d.h(3.14f);
}
 
int main()
{
  Derived d;
  sample(d, d);
}

(1) This is not hidden (good!)

The output of this program demonstrates that the behavior depends on the type of the object, not the type of the reference:

Derived::f(float)
Derived::f(float)
Derived::g(float)
Derived::g(float)
Derived::h(float)
Derived::h(float)

These guidelines apply only to public inheritance; hiding base class member functions is fine for private or protected inheritance (see FAQ 37.01).

FAQ 29.04 What should a derived class do when it redefines some but not all of a set of overloaded member functions inherited from the base class?

The derived class should use the using syntax.

If the base class has an overloaded set of member functions and the derived class overrides some but not all of that set, the redefined member functions will hide the other overloads. The work-around is to use the using syntax. The following example shows class Base with two overloaded member functions called f.

#include 
using namespace std;
 
class Base {
public:
  virtual ~Base()         throw();
  virtual void f(int x)   throw();
  virtual void f(float x) throw();
};
 
Base::~Base() throw()
{ }
 
void Base::f(int x) throw()
{ cout << "Base::f(int)\n"; }
 
void Base::f(float x) throw()
{ cout << "Base::f(float)\n"; }

Now suppose the author of class Derived wants to override one of the two f() member functions. In this case the derived class should also say using Base::f; to avoid confusing users:

class Derived : public Base {
public:
  virtual void f(int x) throw();
  using Base::f;                                     <-- 1
};
 
void Derived::f(int x) throw()
{ cout << "Derived::f(int)\n"; }

(1) This unhides f(float) (good!)

Because of the using Base::f; line in the derived class, f(float) is not hidden:

void sample(Base& b, Derived& d)
{
  b.f(42);
  d.f(42);
  b.f(3.14f);
  d.f(3.14f);                                        <-- 1
}
int main()
{
  Derived d;
  sample(d, d);
}

(1) This is not hidden (good!)

The output of this program demonstrates that the behavior depends on the type of the object, not the type of the reference:

Derived::f(int)
Derived::f(int)
Base::f(float)
Base::f(float)

This guideline applies only to public inheritance; hiding base class member functions is fine for private or protected inheritance.

FAQ 29.05 Can virtual functions be overloaded?

Yes, but it's often easier to use nonvirtual overloads that call nonoverloaded virtuals.

, when virtual member functions are overloaded, the hiding rule forces derived classes to do a bit more work than necessary. In these situations, it is often easier if the overloads are nonvirtuals that call virtuals that aren't overloaded. These nonoverloaded virtuals are normally protected:.

The following code shows how to apply this guideline to the situation in the previous FAQ where Base::f(int) and Base::f(float) are overloaded virtuals. These functions are now nonvirtuals that call nonoverloaded virtuals f_i(int) and f_f(float). (Don't redefine nonvirtual member functions; see FAQ 29.02.)

#include 
using namespace std;
 
class Base {
public:
  virtual ~Base() throw();
  void f(int x)   throw();
  void f(float x) throw();
protected:
  virtual void f_i(int x)   throw();
  virtual void f_f(float x) throw();
};
inline void Base::f(int x) throw()                   <-- 1
  { f_i(x); }
inline void Base::f(float x) throw()
  { f_f(x); }
void Base::f_i(int x) throw()                        <-- 2
  { cout << "Base::f(int)\n"; }
void Base::f_f(float x) throw()
  { cout << "Base::f(float)\n"; }
 
Base::~Base() throw()
  { }

(1) Overloaded nonvirtuals

(2) Nonoverloaded virtuals

In class Derived, the behavior of f(int) is changed by overriding Base::f_i(int); redefining f(int) itself would be wrong, since a redefinition would hide Base::f(float).

class Derived : public Base {
public:
                                                     <-- 1
protected:
  virtual void f_i(int x) throw();                   <-- 2
};
 
void Derived::f_i(int x) throw()
  { cout << "Derived::f(int)\n"; }

(1) Derived classes never redefine f(int)

(2) Derived classes may override f_i(int)

Now when member function f(int) is invoked on a Derived object, it expands inline as the code of Base::f(int), which calls protected member function f_i(int), and since f_i(int) is virtual, it resolves to the correct member function using dynamic binding (see FAQ 2.24). The message here is that both f(int) and f(float) work correctly on both a Derived& and on a Base&:

void sample(Base& b, Derived& d)
{
  b.f(42);
  d.f(42);
 
  b.f(3.14f);
  d.f(3.14f);                                        <-- 1
}
 
int main()
{
  Derived d;
  sample(d, d);
}

(1) This is not hidden (good!)

The output of this program demonstrates that the behavior depends on the type of the object, not the type of the reference:

Derived::f(int)
Derived::f(int)
Base::f(float)
Base::f(float)

This approach is more scalable than the approach presented in the earlier FAQ. It is scalable in two ways, with respect to the code and with respect to the people. With respect to the code, the root of the inheritance hierarchy has a few extra lines of code, but none of the (potentially many) derived classes need have any extra code to handle the hiding rule. This is a good trade-off since an inheritance hierarchy often has many derived classes. With respect to the people, the developer of the root class of the inheritance hierarchy needs to understand the hiding rule, but all the writers of all the derived classes can remain relatively ignorant of it—they need to know only that they are to override the virtual member functions rather than the nonvirtual member functions. This is a good trade-off because the developers who build the root classes in the inheritance hierarchies are normally more sophisticated than the developers who build the derived classes.

Note that this approach does not imply any performance overhead, since the overloaded public: member functions are normally inline nonvirtuals.

As before, this guideline applies only to public inheritance; hiding base class member functions is fine for private or protected inheritance .

Read full story