answersLogoWhite

0


Best Answer

Polymorphism is the ability to use an operator or function in different ways. Polymorphism gives different meanings or functions to the operators or functions. Poly, referring to many, signifies the many uses of these operators and functions. A single function usage or an operator functioning in many ways can be called polymorphism. Polymorphism refers to codes, operations or objects that behave differently in different contexts.

User Avatar

Wiki User

13y ago
This answer is:
User Avatar
More answers
User Avatar

Wiki User

9y ago

There are two types of polymorphism: static and dynamic. Static polymorphism applies to templates (both functions and classes), where the compiler generates the specific function or class according to the types you use with the template. Dynamic polymorphism is achieved at runtime through virtual functions. This ensures that the most derived implementation of a function is called regardless of which base class interface is used to invoke the function.

This answer is:
User Avatar

User Avatar

Wiki User

10y ago

Compile-time polymorphism is a somewhat vague term, but essentially it describes the way in which overloaded function calls and template parameters are resolved at compile time.

For instance, if we overload the max function as follows:

int max(int x, int y){ return(y<x?x:y); }

float max(float x, float y){ return(y<x?x:y); }

The compiler can determine which version of the function to call from the parameter types we pass to it. If we pass int types, the first version is called, otherwise the second is called. Since the compiler resolves the calls polymorphically, this is what we mean by compile-time polymorphism.

We can achieve the same thing with a template function:

template<typename T>

T max(T x, T y){ return(y<x?x:y); }

This time the compiler generates the appropriate overloads for us according to the types we pass, and polymorphically determines which overload to call.

Templates can also be used with classes. Thus std::vector<int> and std::vector<float> are STL classes that are generated and instantiated using compile-time polymorphism, according to the specific types we pass.

This answer is:
User Avatar

User Avatar

Wiki User

10y ago

Runtime polymorphism is the means by which we can write generic code that invokes specific behaviour without the need to employ expensive runtime type information. That is, if we design several classes that share common features, we can percolate that shared functionality up to a common base class and work with those generic classes rather than the more specific classes. By declaring all the common functionality as virtual methods of the base class, and implementing the more specific methods in the derived class overrides, the virtual table then handles runtime type information, rather than relying on the programmer to "do the right thing".

This answer is:
User Avatar

User Avatar

Wiki User

11y ago

Consider the example, below. Here we've declared a base class Base and two derived classes, Derived1 and Derived2, both of which are derived from Base. Foo() is declared virtual in Base and both Derived1 and Derived2 provide implementations for Foo(), as does Base itself. We've also declared a function, Bar(), which accepts a reference to Base.

In the main function, we declare a pointer to Base, b. We then instantiate a new instance of Base and assign its memory address to b, and then pass it by reference to Bar(), which calls the Base::Foo() method. Upon returning, the Base object is deleted.

We then use this same pointer to instantiate a new instance of Derived1 and repeat the process. Finally, we repeat the process one last time with a new instance of Derived2.

Firstly, you will notice that although b is declared as pointer to an instance of Base, we can point it to instances of Derived1 and Derived2. This is because both Derived1 and Derived2 are a kind of Base.

The second thing to notice is that although Bar() only accepts a reference to Base, we can still pass references to Derived1 and Derived2, because, again, they are a kind of Base.

Finally, when the Bar() function calls the base.Foo() method, you will notice that each call produces a different result. Even though Foo() does not know whether base is an instance of Base, Derived1 or Derived2, it has exhibited the correct behaviour without the need for runtime information or dynamic casting.

This is the essence of polymorphism. That is, you can work with base classes that provide a common, generic, virtual interface to derived types without any regard to their actual type. When you call virtual methods of the base class, you actually call the most-derived method. This is achieved via the v-table, which is automatically generated whenever a base class contains virtual methods.

#include

using namespace std;

class Base

{

public:

virtual void Foo(){ cout << "Base::Foo()\n"; }

}

class Derived1 : public Base

{

public:

virtual void Foo(){ cout << "Derived1::Foo()\n"; }

}

class Derived2 : public Base

{

public:

virtual void Foo(){ cout << "Derived2::Foo()\n"; }

}

void Bar( const Base & base )

{

base.Foo();

}

int main()

{

Base * b = NULL;

b = new Base(); Bar( *b ); delete( b );

b=new Derived1(); Bar( *b ); delete( b );

b=new Derived2(); Bar( *b ); delete( b );

return( 0 );

}

This answer is:
User Avatar

User Avatar

Wiki User

10y ago

Dynamic polymorphism is achieved using virtual methods. However, only nonstatic member functions can be declared virtual. Static polymorphism overcomes this problem, allowing static member functions to work polymorphically.

Before we look at a working example, let's first consider the problem. The following code uses a static method in the base class but we want the derived class to provide the implementation and we want to be able to invoke that implementation polymorphically through the base class.

#include<iostream>

#include<string>

class Base

{

public:

static std::string Method()

{

return "Base::Method";

}

};

class Derived: public Base

{

public:

static std::string Method()

{

return "Derived::Method";

}

};

int main()

{

Base* B = new Derived();

std::cout << B->Method() << "\n";

}

Output:

Base::Method

That's not what we want at all. Although we're invoking B->Method(), B is actually an instance of Derived so we really wanted to invoke Derived::Method() not Base::Method(). Had we not declared these methods static we could simply declare them virtual to get the expected behaviour, but that doesn't really help when the function absolutely has to be static.

To get around this problem, we can use the "curious recurring template pattern" or CRTP. This technique makes use of the fact that a derived class can pass itself as a template parameter to its own base class. It's an advanced technique, but one that can be easily demonstrated:

#include<iostream>

#include<string>

template< class CRTP_DerivedType >

class CRTP_Base

{

public:

static std::string Method()

{

return CRTP_DerivedType::Method();

}

};

class CRTP_Derived: public CRTP_Base< CRTP_Derived >

{

public:

static std::string Method()

{

return "CRTP_Derived::Method";

}

};

int main()

{ CRTP_Base<CRTP_Derived>* B = new CRTP_Base<CRTP_Derived>();

std::cout << B->Method() << std::endl;

}

Output:

CRTP_Derived::Method()

The syntax is ugly, but at least we can now invoke static methods polymorphically.

Note that we can also invoke instance methods using static polymorphism. The only difference is that we must statically cast the implicit this pointer to the template type before invoking the override.

Fortunately, there are relatively few occasions where static polymorphism is absolutely necessary -- such as when the overhead of dynamic polymorphism becomes detrimental to performance, which is rarely the case. But if you need polymorphic static methods then static polymorphism is the only way to achieve it. There are other ways of achieving static polymorphism but CRTP is the simplest.

This answer is:
User Avatar

User Avatar

Wiki User

11y ago

Dynamic polymorphism is polymorphism that is resolved only at runtime. Consider the following example:

class A{

data members;

methods;

void display();

}


class B : public A{

data members;

methods;

void display();

}


int main(){

A obj;

B obj1;

A *ptr;

ptr = obj;

obj->display();//Here the display defined in A is called

ptr = obj1;

obj1->display();//Here the display defined in B is called

return 0;

}


As seen in the above example, the display function is overloaded in the base and derived class. The calls to display using a pointer will be resolved at run-time. Hence it is run-time polymorphism.

This answer is:
User Avatar

User Avatar

Wiki User

7y ago

Runtime polymorphism is achieved through the use of virtual functions and/or pure-virtual functions. A virtual function is a base class function that is expected to be overridden by a derived class. A pure-virtual function is an abstract base class function that must be overridden by a derived class. Whenever we implicitly invoke a virtual function (whether pure or non-pure), the most-derived override of that function will be invoked, even if we do not know the precise runtime type of the object that provides that override.

Consider the following:

class foo {

public:

virtual void action (void);

// ...

};

void f (foo& object) {

object.action();

}

The foo class has at least one virtual function and this immediately tells us that the foo class is intended to be used as a base class. The f() function accepts a reference argument of type foo, thus it "knows" all about objects of type foo, but knows nothing about classes that derive from foo. Elsewhere in our code (even in a completely different translation unit) we might have the following:

class bar : public foo {

void action (void) override;

};

The bar class derives from foo and provides an override for the virtual function it publicly inherited from foo. The f() function doesn't know anything about this new class of object, but because foo is a public base of bar, a bar is a kind of foo so the following is perfectly valid:

bar b;

f (b);

Although the f() function knows nothing about objects of type bar, it does know about its public base class, foo, and therefore knows it has a virtual function named action(). When f() invokes that function, rather than invoking foo::action() as we might expect, we actually invoke bar::action(), because bar provides an override and it is the most-derived override for all objects of type bar.

This is achieved through a virtual table, or vtable. Every class of object that declares, inherits or overrides a virtual function has a (hidden) static member vtable. The vtable is a simple structure that contains a list of function pointers, one for each virtual function declared, inherited or overridden by the class. The vtable for an object of type foo will refer to foo::action() while the vtable for an object of type bar will refer to bar::action(). When we pass a reference to an object of type bar to the f() function, the vtable it uses will be the one provided by the bar class rather than the foo class, thus bar::action() is invoked instead of foo::action(), thus achieving runtime polymorphic behaviour.

Note that in order to achieve polymorphic behaviour, polymorphic objects must be passed to functions by reference or by pointer, never by value. If we pass by value, the object will be "sliced":

void g (foo f) {

f.action();

}

In the above example, if we pass a bar object into g(), the object will be copied into f. However, f is a foo value, not a bar value, so the bar portion of our object will be omitted from the copy, along with its vtable, thus slicing the object. When we invoke f.action(), we actually invoke foo::action() instead of bar::action(). For an otherwise polymorphic object this would be considered a design error, so it is important that we avoid slicing objects; always pass objects by reference when a function needs to invoke the object's virtual methods.

When we override a virtual function, we often want to invoke the base class method as part of that override. This can be achieve by invoking the method explicitly

void bar::action (void) {

foo::action(); // invoke the base class method

// invoke methods specific to the bar class...

}

We can invoke specific methods before and/or after invoking the base class method, depending on our needs. If we have no specific methods to invoke, then we do not need to override the base class method; the vtable for bar will simply refer to the base class method. However, had foo declared action() to be a pure-virtual function rather than just a virtual function, then we'd have to provide an override, even if that override simply invoked the base class method. If we do not provide an override, the bar class becomes an abstract base class just like foo.

Abstract base classes cannot be instantiated other than by derivation. Classes derived from abstract base classes can only be instantiated if they provide or inherit an override for each pure-virtual function declared by the abstract base classes, otherwise they too become abstract base classes. The class that introduces a pure-virtual function need not provide a default implementation for it (it is optional for pure-virtual functions but mandatory for virtual functions). Even if a default implementation is provided, it cannot be inherited by derived classes -- only pure-virtual function overrides can be inherited by derived classes. Once overridden by a class, a pure-virtual method reverts to a normal virtual function with respect to all derivatives of that class.

When a virtual function override is declared final in a class, that function cannot be overridden by derivatives of the class. When the class itself is declared final, it cannot be used as a base class.

In contrast to runtime polymorphism, compile-time polymorphism is achieved through the use of templates and template metaprogramming. This type of polymorphism bears no relation to the runtime polymorphism mechanism which is achieved through vtables and virtual methods.

This answer is:
User Avatar

User Avatar

Wiki User

7y ago

In C++, compile-time polymorphism is achieved through the use of template metaprogramming while runtime polymorphism is achieved through virtual functions.

This answer is:
User Avatar

Add your answer:

Earn +20 pts
Q: Define polymorphism in c plus plus?
Write your answer...
Submit
Still have questions?
magnify glass
imp
Related questions

Is overriding a dynamic polymorphism in c plus plus or not?

In C++, overriding and function, method, or operator is a different thing than (dynamic) polymorphism, so overriding a polymorphic method is almost entirely possible.


What are the concepts of object oriented programming in c plus plus?

The concepts of OOP in C++ are the same as for OOP in any other programming language: abstraction, encapsulation, inheritance and polymorphism.


Does c language support polymorphism?

C++ does.


What are the main features of OOP in c plus plus?

The main features of OOP are the same regardless of the language. They are: encapsulation; data hiding; inheritance; and polymorphism.


Define compile time polymorphism with short examples?

compiler can decide which form of the object should be invoked during compile time.this type of polymorphism is know as compile time polymorphism


What are the various concepts of c plus plus?

1.Classes and Objects 2.Constructors and Destructors 3.Inheritance 4.Polymorphism 5.Dynamic Binding


How do you write a macro to find the biggest of 3 numbers in c plus plus?

#define biggest (a) &gt; (b) &amp;&amp; (a) &gt; (c) ? (a) : (b) &gt; (c) ? (b) : (c)


How do you find a largest algorithm in c plus plus?

#define max (a, b) ((a) &gt;= (b)) ? (a) : (b)


Is there a file concept in c plus plus?

No. The standard does not define nor require a file concept.


If a plus b plus c not equal to 0 then a divided by b plus c equals b divided by c plus a equals c divided by a plus b prove that a equals b equals c?

Because there is no way to define the divisors, the equations cannot be evaluated.


Why is c plus plus regarded as being a hybrid language?

C++ is regarded as hybrid because it is both procedural and objected oriented. A pure c program can be compiled and run on a c++ platform. At the same time, c++ also provides object oriented features like classes, polymorphism, encapsulation, abtraction, etc.


Define protected in c plus plus?

Protected members are like private members, but are also accessible to derived classes.