• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 297,  comments - 15,  trackbacks - 0
            from http://en.wikipedia.org/wiki/Virtual_function

            Virtual function

            From Wikipedia, the free encyclopedia

            Jump to: navigation, search

            In object-oriented programming, a virtual function or virtual method is one whose behavior can be overridden within an inheriting class by a function with the same signature. This concept is a very important part of the polymorphism portion of object-oriented programming (OOP).

            Contents

            [hide]

            [edit] Purpose

            The concept of the virtual function solves the following problem:

            In OOP when a derived class inherits from a base class, an object of the derived class may be referred to (or cast) as either being the base class type or the derived class type. If there are base class functions overridden by the derived class, a problem then arises when a derived object has been cast as the base class type. When a derived object is referred to as being of the base's type, the desired function call behavior is ambiguous.

            The distinction between virtual and not virtual resolves this ambiguity. If the function in question is designated "virtual" in the base class then the derived class's function would be called (if it exists). If it is not virtual, the base class's function would be called.

            Virtual functions overcome the problems with the type-field solution by allowing the programmer to declare functions in a base class that can be redefined in each derived class.

            [edit] Example

            For example, a base class Animal could have a virtual function eat. Subclass Fish would implement eat() differently than subclass Wolf, but you can invoke eat() on any class instance referred to as Animal, and get the eat() behavior of the specific subclass.

            This allows a programmer to process a list of objects of class Animal, telling each in turn to eat (by calling eat()), with no knowledge of what kind of animal may be in the list. You also do not need to have knowledge of how each animal eats, or what the complete set of possible animal types might be.

            [edit] C++

            The following is an example in C++. Note that this example is not exception-safe. In particular, it may leak resources if new or vector::push_back throws an exception.

            #include <iostream>
            #include <vector>

            using namespace std;
            class Animal
            {
            public:
            virtual void eat() const { cout << "I eat like a generic Animal." << endl; }
            virtual ~Animal() {}
            };

            class Wolf : public Animal
            {
            public:
            void eat() const { cout << "I eat like a wolf!" << endl; }
            };

            class Fish : public Animal
            {
            public:
            void eat() const { cout << "I eat like a fish!" << endl; }
            };

            class GoldFish : public Fish
            {
            public:
            void eat() const { cout << "I eat like a goldfish!" << endl; }
            };


            class OtherAnimal : public Animal
            {
            };

            int main()
            {
            std::vector<Animal*> animals;
            animals.push_back( new Animal() );
            animals.push_back( new Wolf() );
            animals.push_back( new Fish() );
            animals.push_back( new GoldFish() );
            animals.push_back( new OtherAnimal() );

            for( std::vector<Animal*>::const_iterator it = animals.begin();
            it != animals.end(); ++it)
            {
            (*it)->eat();
            delete *it;
            }

            return 0;
            }

            Output with the virtual function Animal::eat():

            I eat like a generic Animal.
            I eat like a wolf!
            I eat like a fish!
            I eat like a goldfish!
            I eat like a generic Animal.

            Output if Animal::eat() were not declared as virtual:

            I eat like a generic Animal.
            I eat like a generic Animal.
            I eat like a generic Animal.
            I eat like a generic Animal.
            I eat like a generic Animal.

            [edit] Java

            In Java, all methods are by default "virtual functions." Only methods marked with the keyword final are non-virtual. The following is an example of virtual methods in Java:

            import java.util.*;

            public class Animal {
            public void eat() { System.out.println("I eat like a generic Animal."); }

            public static void main(String[] args) {
            List<Animal> animals = new LinkedList<Animal>();

            animals.add(new Animal());
            animals.add(new Wolf());
            animals.add(new Fish());
            animals.add(new OtherAnimal());

            for (Animal currentAnimal : animals) {
            currentAnimal.eat();
            }
            }
            }

            public class Wolf extends Animal {
            public void eat() { System.out.println("I eat like a wolf!"); }
            }

            public class Fish extends Animal {
            public void eat() { System.out.println("I eat like a fish!"); }
            }

            public class OtherAnimal extends Animal {}

            Output:

            I eat like a generic Animal.
            I eat like a wolf!
            I eat like a fish!
            I eat like a generic Animal.

            [edit] C#

            In C#, a base class must provide the virtual modifier for any virtual method, and derived classes must provide the override modifier for any overriden method inherited from a base class. The following is an example in C#:

            using System;
            using System.Collections.Generic;

            namespace ConsoleApplication1
            {
            public class Animal
            {
            public virtual void eat()
            {
            Console.WriteLine("I eat like a generic Animal.");
            }
            }

            public class Wolf : Animal
            {
            public override void eat()
            {
            Console.WriteLine("I eat like a wolf!");
            }
            }

            public class Fish : Animal
            {
            public override void eat()
            {
            Console.WriteLine("I eat like a fish!");
            }
            }

            public class GoldFish : Fish
            {
            public override void eat()
            {
            Console.WriteLine("I eat like a goldfish!");
            }
            }

            public class OtherAnimal : Animal
            {
            // eat() method is not overridden, so the base class method will be used.
            }

            class Program
            {
            static void Main(string[] args)
            {
            List<Animal> animals = new List<Animal>();

            animals.Add(new Animal());
            animals.Add(new Wolf());
            animals.Add(new Fish());
            animals.Add(new GoldFish());
            animals.Add(new OtherAnimal());

            foreach (Animal currentAnimal in animals)
            {
            currentAnimal.eat();
            }
            }
            }
            }

            Output:

            I eat like a generic Animal.
            I eat like a wolf!
            I eat like a fish!
            I eat like a goldfish!
            I eat like a generic Animal.

            [edit] VB.NET

            In VB.NET, a base class must provide the Overridable modifier for any virtual method, and derived classes may provide the optional Overrides modifier for any overriden method inherited from a base class (this prevents a warning from being issued). The following is an example in VB.NET:

            Imports System
            Imports System.Collections.Generic

            Namespace ConsoleApplication1

            Public Class Animal
            Public Overridable Sub eat()
            Console.WriteLine("I eat like a generic Animal.")
            End Sub
            End Class

            Public Class Wolf
            Inherits Animal
            Public Overrides Sub eat()
            Console.WriteLine("I eat like a wolf!")
            End Sub
            End Class

            Public Class Fish
            Inherits Animal
            Public Overrides Sub eat()
            Console.WriteLine("I eat like a fish!")
            End Sub
            End Class

            Public Class Goldfish
            Inherits Fish
            Public Overrides Sub eat()
            Console.WriteLine("I eat like a goldfish!")
            End Sub
            End Class

            Public Class OtherAnimal
            Inherits Animal
            'eat() method is not overridden, so the base class method will be used.
            End Class

            Public Class Program
            Shared Sub Main()
            Dim animals As New List(Of Animal)
            animals.Add(New Animal())
            animals.Add(New Wolf())
            animals.Add(New Fish())
            animals.Add(New Goldfish())
            animals.Add(New OtherAnimal())

            For Each currentAnimal As Animal In animals
            currentAnimal.eat()
            Next
            End Sub
            End Class

            End Namespace

            Output:

            I eat like a generic Animal.
            I eat like a wolf!
            I eat like a fish!
            I eat like a goldfish!
            I eat like a generic Animal.


            [edit] Abstract classes and pure virtual functions

            A pure virtual function or pure virtual method is a virtual function that is required to be implemented by a derived class that is not abstract. Classes containing pure virtual methods are termed "abstract;" they cannot be instantiated directly, and a subclass of an abstract class can only be instantiated directly if all inherited pure virtual methods have been implemented by that class or a parent class. Pure virtual methods typically have a declaration (signature) and no definition (implementation).

            As an example, an abstract base class "MathSymbol" may provide a pure virtual function doOperation(), and derived classes "Plus" and "Minus" implement doOperation() to provide concrete implementations. Implementing doOperation() would not make sense in the "MathSymbol" class as "MathSymbol" is an abstract concept whose behaviour is defined solely for each given kind (subclass) of "MathSymbol". Similarly, a given subclass of "MathSymbol" would not be complete without an implementation of doOperation().

            Although pure virtual methods typically have no implementation in the class that declares them, pure virtual methods in C++ are permitted to contain an implementation in their declaring class, providing fallback or default behaviour that a derived class can delegate to if appropriate.

            Pure virtual functions are also used where the method declarations are being used to define an interface for which derived classes will supply all implementations. An abstract class serving as an interface contains only pure virtual functions, and no data members or ordinary methods. Use of purely abstract classes as interfaces works in C++ as it supports multiple inheritance. Because many OO languages do not support multiple inheritance they often provide a separate interface mechanism. This is seen in Java for example.

            [edit] C++

            In C++, pure virtual functions are declared using a special syntax [ = 0 ] as demonstrated below.

            class Abstract {
            public:
            virtual void pure_virtual() = 0;
            };

            The pure virtual function declaration provides only the prototype of the method. Although an implementation of the pure virtual function is typically not provided in an abstract class, it may be included, although the definition may not be included at the point of declaration [1]. Every non-abstract child class is still required to override the method, but the implementation provided by the abstract class may be called in this way:

             void Abstract::pure_virtual() {
            // do something
            }

            class Child : public Abstract {
            virtual void pure_virtual(); // no longer abstract, this class may be
            // instantiated.
            };

            void Child::pure_virtual() {
            Abstract::pure_virtual(); // the implementation in the abstract class
            // is executed
            }

            [edit] Java (and C#)

            In Java (and C#), pure virtual methods are declared using the abstract keyword. Such a method cannot have a body. A class containing abstract methods (either directly, or inherited and not overridden) must itself be declared abstract. (But the converse is not true - an abstract class is not required to have any abstract methods.) An abstract class cannot be instantiated.

            abstract class B {
            abstract void a_pure_virtual_function();
            }

            Java also uses interfaces. All of the methods declared in an interface are implicitly abstract:

            interface C {
            void a_pure_virtual_function();
            }

            [edit] Behavior During Construction and Destruction

            Languages differ in their behaviour while the constructor or destructor of an object is running. For some languages, notably C++, the virtual dispatching mechanism has different semantics during construction and destruction of an object. While it is recommended that virtual function calls in constructors should be avoided for C++ [2], in some other languages, for example Java and C#, the derived implementation can be called during construction and design patterns such as the Abstract Factory Pattern actively promote this usage in languages supporting the ability.

            [edit] C++

            #include <iostream>
            #include <string>

            using namespace std;

            struct A
            {
            virtual string name() const { return "A"; }
            virtual ~A() { cout << "Destructing " << name(); }
            };

            struct B : A
            {
            B() { cout << "Constructing " << name() << endl; }
            virtual string name() const { return "B"; }
            };

            struct C : B
            {
            virtual string name() const { return "C"; }
            };

            int main()
            {
            C c; // Output: "Constructing B"

            } // Output: "Destructing A"

            [edit] Java

            public class Base {
            public int length() { return 0; }
            public Base()
            {
            System.out.println("Constructing " + length());
            }

            static class Derived extends Base {
            String name_;
            public Derived(String name)
            {
            name_ = name != null ? name : ""; // Class invariant name_ is not null
            }
            public int length() { return name_.length(); } // Assume name_ is not null
            }

            public static void main(String[] args)
            {
            new Derived("Ooops"); // NullPointerException, Derived.name_ has not been assigned to yet
            }
            }

            This is because the constructor of Base is executed before the constructor of Derived. As the constructor of Base calls length(), a null pointer exception is thrown.

            [edit] Virtual destructors

            Object-oriented languages typically manage memory allocation and deallocation automatically when objects are created and destroyed, however some object-oriented languages allow a custom destructor method to be implemented if desired. One such language is C++, and as illustrated in the following example, it is important for a C++ base class to have a virtual destructor to ensure that the destructor from the most derived class will always be called.

            In the example below having no virtual destructor, while deleting an instance of class B will correctly call destructors for both B and A if the object is deleted as an instance of B, an instance of B deleted via a pointer to its base class A will produce undefined behaviour.[3] On many implementations, the destructor for B will not be called in this situation.

             #include <iostream>
            using namespace std;

            class A
            {
            public:

            A() { }
            ~A() { cout << "Destroy A" << endl; }
            };

            class B : public A
            {
            public:

            B() { }
            ~B() { cout << "Destroy B" << endl; }
            };

            int main()
            {
            A* b1 = new B;
            B* b2 = new B;

            delete b1; // According to the C++ standard,
            // the behaviour of this is undefined.
            // Usually, only ~A() is called though b1 is an instance
            // of class B because ~A() is not declared virtual.
            delete b2; // Calls destructors ~B() and ~A()

            return 0;
            }

            Possible output:

            Destroy A
            Destroy B
            Destroy A

            Correctly declaring the destructor for class A as virtual ~A() will ensure that the destructor for class B is called in both cases with the example above.

            [edit] See also

            [edit] References

            1. ^ Standard C++ 98 - 10.4/2
            2. ^ Meyers, Scott (June 6, 2005). "Never Call Virtual Functions during Construction or Destruction". http://www.artima.com/cppsource/nevercall.html. 
            3. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §5.3.5 Delete [expr.delete] para. 3


            posted on 2009-04-19 23:32 chatler 閱讀(868) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C++_BASIS
            <2009年11月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺(jué)這個(gè)博客還是不錯(cuò),雖然做的東西和我不大相關(guān),覺(jué)得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            亚洲AV无码一区东京热久久| 狠狠人妻久久久久久综合蜜桃| 亚洲精品白浆高清久久久久久| 久久精品人人做人人爽97| 99久久精品免费看国产一区二区三区| 久久久久久久波多野结衣高潮| 伊人丁香狠狠色综合久久| 国产精品福利一区二区久久| 新狼窝色AV性久久久久久| 久久免费看黄a级毛片| 欧美日韩久久中文字幕| 无码人妻少妇久久中文字幕| 精品视频久久久久| 久久久噜噜噜久久| 久久国产香蕉一区精品| 蜜臀久久99精品久久久久久| 欧美亚洲另类久久综合婷婷| 一97日本道伊人久久综合影院| 香港aa三级久久三级老师2021国产三级精品三级在 | 亚洲色婷婷综合久久| 久久www免费人成看片| 人妻丰满AV无码久久不卡| 久久发布国产伦子伦精品 | 亚洲成人精品久久| 久久精品国产国产精品四凭| 亚洲一区精品伊人久久伊人 | 93精91精品国产综合久久香蕉| 久久久精品日本一区二区三区 | 久久99精品久久只有精品| 久久亚洲国产中v天仙www| 久久久中文字幕日本| 久久久久久久久久久久久久| 精品免费久久久久久久| 国内精品伊人久久久久网站| 国产精品成人久久久| 99久久成人国产精品免费| 久久天天日天天操综合伊人av| 国产69精品久久久久9999APGF| 久久免费精品一区二区| 精品国产乱码久久久久软件| 久久精品九九亚洲精品|