精华内容
下载资源
问答
  • virtual关键字的作用
    2021-11-10 16:41:51

    在实际应用中,子类仅能重写父类中的虚方法或者抽象方法,
    当要重写父类方法内容时,将其定义成抽象方法,或将方法定义成虚方法。

    更多相关内容
  • 1.virtual关键字主要是什么作用?c++中的函数调用默认不适用动态绑定。要触发动态绑定,必须满足两个条件:第一,指定为虚函数;第二,通过基类类型的引用或指针调用。由此可见,virtual主要主要是实现动态绑定。 2....
  • EF实体类种的Virtual关键字作用

    千次阅读 2020-05-17 20:36:54
    在使用EF中我们会使用导航属性,其中会加上Virtual关键字,这个有什么作用呢。加了此关键字就可以使用lazyload懒加载,不加此特性的话是加载不出此导航属性的内容的。 例子,有两个实体sys_user 和 sys_dep ...

    在使用EF中我们会使用导航属性,其中会加上Virtual关键字,这个有什么作用呢。加了此关键字就可以使用lazyload懒加载,不加此特性的话是加载不出此导航属性的内容的。

    例子,有两个实体sys_user 和 sys_dep

        public partial class sys_user
        {
            [Key]
            [StringLength(50)]
            public string account { get; set; }
    
            [StringLength(50)]
            public string name { get; set; }
    
            [StringLength(50)]
            public string password { get; set; }
    
            public int? age { get; set; }
    
            [StringLength(50)]
            public string sex { get; set; }
    
            [StringLength(50)]
            public string depid { get; set; }
    
            [StringLength(50)]
            public string status { get; set; }
    
            [StringLength(50)]
            public string roleid { get; set; }
            public virtual sys_dep sys_dep { get; set; }
        }
        public partial class sys_dep
        {
            [Key]
            [StringLength(50)]
            public string depid { get; set; }
    
            [StringLength(50)]
            public string depname { get; set; }
    
            [StringLength(50)]
            public string manager { get; set; }
        }
                using (oaEntities db = new oaEntities()) {
                    db.Database.Log = s => { Console.WriteLine(s); };
                    var q = db.sys_user.Select(b => b);
                    foreach (var item in q) {
                        Console.WriteLine($"User Show:{item.account},{item.name},{item.sys_dep.depname}");
                    }
                }

    可以看到将sys_dep的depname信息显示出来了

    下面我们把Virtual关键字拿掉改为        public sys_dep sys_dep { get; set; }

    重新运行后就会出现如此错误了

    展开全文
  • 1.virtual关键字主要是什么作用? c++中的函数调用默认不适用动态绑定。要触发动态绑定,必须满足两个条件:第一,指定为虚函数;第二,通过基类类型的引用或指针调用(多态产生的条件)。 由此可见,virtual主要...

    对virtual关键的理解需要结合其应用场景来分析。以下从多个角度来深入理解virtual关键字。

    1.virtual关键字主要是什么作用?

    c++中的函数调用默认不适用动态绑定。要触发动态绑定,必须满足两个条件:第一,指定为虚函数;第二,通过基类类型的引用或指针调用(多态产生的条件)。
    由此可见,virtual主要主要是实现动态绑定。

    2.哪些情况下可以使用virtual关键字?

    virtual可用来定义类函数和应用到虚继承(一个是多态应用到函数,一个虚继承应用到类)。

    友元函数 构造函数 static静态函数 不能用virtual关键字修饰(请思考为什么?—静态链编);
    普通成员函数 和析构函数 可以用virtual关键字修饰;

    3.virtual函数的效果

    class GrandFather
    { public:
     GrandFather() {}
     virtual void fun()
     {  cout << "GrandFather call function!" << endl;
      }
    };
    
    
    class Father : public GrandFather
    { public:
      Father() {}
      void fun()
      {  cout << "Father call function!" << endl;
      }
    };
    
    class Son : public Father
    {  public:
       Son() {}
       void fun()
      {    cout << "Son call function!" << endl;
      }
    };
    
    void print(GrandFather* father)
    { father->fun();
    }
    
    int _t main(int argc, _TCHAR* argv[])
    { Father * pfather = new Son;
            pfather->fun();
            GrandFather * pgfather = new Father;
            print(pgfather);
     return 0;
    }
    

    输出为 Son call function

       Father call function
    

    这就是实现多态的效果!

    4.virtual的继承性

    只要基函数定义了virtual,继承类的该函数也就具有virtual属性
    即 GrandFather Father Son同时定义virtual void fun()与GrandFather一个定义virtual void fun效果是一样的

    5.虚析构函数

    class GrandFather
    { public:
      GrandFather() {}
      virtual void fun()
     {  cout << "GrandFather call function!" << endl;
     }
    
    
     ~GrandFather()
     { cout << "GrandFather destruction!" << endl;
     }
    };
    
    class Father : public GrandFather
    { public:
      Father() {}
      void fun()
      {   cout << "Father call function!" << endl;
      }
    
     ~Father()
     { cout << "Father destruction!" << endl;
     }
    };
    
    class Son : public Father
    { public:
      Son() {}
      void fun()
     { cout << "Son call function!" << endl;
     }
    
      ~Son()
     { cout << "Son destruction!" << endl;
      }
    };
    
    void print(GrandFather* p)
    { p->fun();
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    { Father * pfather = new Son;
      delete pfather;
      return 0;
    }
    

    以上代码输出:
    Father destruction! GrandFather destruction!
    执行了Son的构造函数,没执行Son的析构函数,故把GrandFather的析构函数设置为virtual
    则输出:
    Son destruction! Father Destruction! GrandFather destruction!

    6. 纯虚函数

    纯虚函数定义如下:

    class GrandFather
    { public:
      GrandFather() {}
      virtual void fun() = 0
     { cout << "GrandFather call function!" << endl;
     }
    
    
     virtual ~GrandFather()
     {
      cout << "GrandFather destruction!" << endl;
     }
    };
    

    纯虚函数为后代类提供可覆盖的接口,但这个类中的版本决不会调用。
    含有(或继续)一个或多个纯虚函数的类是抽象基类,抽象基类不能实例化!
    继承类只有重写这个接口才能被实例化

    7.虚继承

    虚继承主要解决交叉继承带来的问题。这里给出一片参考文章c++虚继承。
    给一个例子如下

    class GrandFather
    { public:
      GrandFather() {}
      void fun()
     { cout << "GrandFather call function!" << endl;
     }
    
    
     virtual ~GrandFather()
     { cout << "GrandFather destruction!" << endl;
     }
    };
    
    class Father1 : public GrandFather
    { public:
      Father1() {}
      void fun()
     { cout << "Father call function!" << endl;
     }
    };
    
    class Father2 : public GrandFather
    { public:
      Father2() {}
      void fun()
     { cout << "Father call function!" << endl;
     }
    
    };
    
    class Son : public Father1, public Father2
    { public:
      Son() {}
     //void fun()
     //{
     // cout << "Son call function!" << endl;
     //}
    };
    
    void print(GrandFather* p)
    { p->fun();
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    { Son* son = new Son;
      son->fun();
      return 0;
    }
    

    编译时会提示报错对fun的访问不明确
    如果Father1和Father2都用虚继承继承GrandFather类则可以解决这个问题

    8. 构造函数和析构函数中的虚函数

    如果在构造函数或析构函数中调用虚函数,则运行的是为构造函数或析构函数自身类型定义的版本

    9.虚函数的实现机制

    关于虚函数的实现机制,我们以后在介绍。

    10.小结

    关于virtual关键字的用法总结如上,有错误或者总结不到位的情况请能帮本人指出!

    11.例子

    class classA
    { public:
      classA()
     { clear();
     }
     virtual ~classA()
     {
      }
     void clear()
     {  memset(this , 0 , sizeof(*this));
     }
     virtual void func()
     {  printf("func\n");
     }
    };
    
    
    class classB : public classA
    {
    };
    
    int main(void)
    {
     classA oa;
     classB ob;
     classA * pa0 = &oa;
     classA * pa1 = &ob;
     classB * pb = &ob;
     oa.func(); // 1
     ob.func(); // 2
     pa0->func(); // 3
     pa1->func(); // 4
     pb->func(); // 5
     return 0;
    }
    

    补充一个例子,这个程序输出依次是

    func
    func
    出错
    func
    func
    

    谈谈我的理解,当

    classA oa;
    oa.func();
    

    不存在动态调用的过程,所以func虽然是虚函数,但是函数调用不通过虚表访问,所以即使

    memset(this , 0 , sizeof(*this));

    找不到虚表地址也没有关系
    在执行classB ob;的时候,注意memset的是classA的地址,所有ob的虚表是存在的
    即是如下,通过指针或引用(动态绑定)访问oa的func函数(需要从虚表访问),会出错
    访问ob的func和函数,无论静态访问还是动态访问,都不会出错

    当把classB的代码改成如下时

    class classB : public classA
    classB()
     {  clear();
     }
     virtual ~classB()
     {
     }
     void clear()
     {  memset(this , 0 , sizeof(*this));
     }
     输出为
    
    func
    func
    出错
    出错
    出错
    
    展开全文
  • 在本文中,只具体介绍new作为修饰符的作用,在用作修饰符时,new关键字可以在派生类中隐藏基类的方法,也就说在使用派生类的方法是调用的方法是New关键字新定义出来的方法,而不是基类的方法。在不使用New关键字
  • virtual关键字作用

    千次阅读 2016-04-07 11:23:19
    1. 在派生类中重新定义基类的方法当需要在派生类中重新定义基类的方法时,应在基类方法... 方法重写注意:使用不使用关键字virtual如果使用了virtual关键字,程序将根据引用或指针指向的 对 象 类 型 来选择方法,否则

    1. 在派生类中重新定义基类的方法


    当需要在派生类中重新定义基类的方法时,应在基类方法前使用关键字virtual,而派生类重新定义的方法自动被继承为虚方法,不过可以加上virtual前缀进行限定,以便区分派生类的哪些方法是虚方法。

    关键字: 基类; 派生类; 虚方法; 方法重写

    注意:使用不使用关键字virtual

    如果使用了virtual关键字,程序将根据引用或指针指向的 对 象 类 型 来选择方法,否则使用引用类型或指针类型来选择方法。

    2. 为多态基类声明virtual析构函数


    为什么要把基类的析构函数设置为虚?

    为多态基类声明virtual析构函数。当class不被企图被当作base class时,令其析构函数为virtual往往是个馊主意。当多重继承时,把基类的析构函数设置为虚函数是一个好习惯,尽管有时候基类析构函数不做任何事情。使用虚析构函数可以保证正确的析构函数被调用;在构造派生类对象时,首先调用基类构造函数,再调用派生类的构造函数;析构对象时恰恰相反。

    关键字: 构造对象;析构对象;构造次序;析构次序

    3. 抽象基类


    把虚方法设置为0,虚方法就是纯虚函数。如:virtual funName() = 0;// 纯虚函数。包含纯虚函数的类只能作为基类,纯虚基类是抽象基类,抽象基类不能创建对象

    如果基类中至少含有一个纯虚函数,那么该基类为抽象基类(Abstract Base Class),抽象基类不能创建对象,抽象基类用于为它的派生类提供接口,派生类必须为其实现纯虚函数。一般抽象基类的纯虚函数(写给编译器看的)不对其定义,但是C++甚至允许抽象基类中的纯虚函数有定义。

    展开全文
  • C++: Virtual关键字的几种用法

    千次阅读 2019-11-06 09:52:10
    c++中的关键字virtual”主要用在两个方面:虚函数与虚基类。下面将分别从这两个方面对virtual进行介绍。1.虚函数 虚函数源于c++中的类继承,是多态的一种。在c++中,一个基类的指针或者引用可以指向或者引用派生...
  • C++ virtual关键字

    千次阅读 2022-02-22 11:32:25
    C++中virtual(虚函数)的用法
  • 关于virtual关键字的用法总结如下,有错误或者总结不到位的情况请能帮本人指出,非常感谢! Virtual是C++ OO机制中很重要的一个关键字。只要是学过C++的人都知...
  • virtual 关键字是面对对象中,用于修饰类中的成员函数的关键字。被 virtual 关键字修饰的函数叫做虚函数。而虚函数本身是实现 C++ 多态的一种方式。 在上图中,我们看到,虚函数属于运行时多态。 那么为什么要使用 ...
  • C# virtual关键字详解

    2021-01-19 14:11:14
    virtual 关键字能修饰方法、属性、索引器以及事件等,用到父类的成员中。使用 virtual 关键字修饰属性和方法的语法形式如下。//修饰属性public virtual 数据类型 属性名{get; set; }//修饰方法访问修饰...
  • 初识多态,剖析virtual关键字

    多人点赞 热门讨论 2022-06-24 08:32:21
    父类中的eat前加了virtual关键字,那么eat函数就被叫做虚函数,这些就满足了多态的条件。此外,doEat函数的参数列表是父类的引用,那么也就满足了多态使用的父类引用或指针指向子类对象。 如果doEat不加引用,那么...
  • 代码如下: class A { public virtual void Func() // 注意virtual,表明这是一个虚拟函数 { Console.WriteLine(“Func In A”); } } class B : A // 注意B是从A类继承,所以A是父类,B是子类 { public override void ...
  • c语言virtual关键字

    千次阅读 2021-05-21 11:59:26
    只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派生类Derived中就可以通过重写虚拟函数来实现对基类虚拟函数的覆盖。当基类Base的指针point指向派生类Derived...
  • 那么把析构函数声明为vitual有什么作用呢?请看下面的代码:#include<iostream>using namespace std; class Base{public: Base() {}; //Base的构造函数 ~Base() //Base的析构函数 { cout << "Output ...
  • MySQL5.7 virtual关键字

    2021-01-19 14:11:22
    本机调试保存数据时报错: Hibernate: /* insert ...果然搜索到virtual是MySQL5.7的新关键字。详见:http://blog.itpub.net/30633755/viewspace-2127708/ 解决方法:修改字段名称virtual改成is_virtual
  • virtual关键字在子类

    2019-09-06 17:37:44
    virtual关键字在父类 析构函数的virtual在子类 间接调用虚函数 完整代码 #include using namespace std; class father { public: void f() { cout()"; } }; class son : public father { public: ...
  • 基础理解和demo 普通的继承 #include class Parent { public: void print() { std::cout << "Parent" << std::endl; } }; class Child : Parent { ...但是如果是 “父类的指针指向子类
  • 在验证工作中经常使用"virtual"关键字,下面列举该关键字应用场景。 主要应用场景在virtual class,virtual interface 以及 virtual task/function。 OOP三大特性(封装,继承,多态)中的多态在SystemVerilog中...
  • 析构函数前加virtual关键字作用?

    千次阅读 2016-06-28 14:39:57
    那么把析构函数声明为vitual有什么作用呢?请看下面的代码: #include using namespace std; class Base { public: Base() {}; //Base的构造函数 ~Base() //Base的析构函数 { cout << "Output from the d
  • @C++面向对象之virtual(转载) ...先从virtual说起 面向对象的三大特征,封装,继承...C++中的virtual关键字修饰方法 约等于 Java中abstract关键字修饰方法。 virtual,望文生义。虚拟的意思。它是用来修饰一个方法的,当
  • virtual关键字--C++Virtual 是C++OO机制中很重要的一个关键字。只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派生类Derived中就可以通过重写虚拟函数来实现...
  • c++之virtual关键字

    千次阅读 2019-04-12 12:43:09
    在c++中,基类必须将它的两种成员函数区分开来, (1)一种是基类希望其派生类进行覆盖(override)的函数。...基类通过在其成员函数的声明语句之前加关键字virtual使得该函数执行动态绑定。 任何...
  • systemverilog:virtual 关键字的用法

    千次阅读 2020-04-24 11:38:10
    我在csdn上查询了systemverilog中关于virtual关键字的用法,发现了这么一句话: “***virtual function/task: 用于OOP思想的继承使用。当定义了virtual时,在子类中调用某function/task,会先查找在子类中是否定义...
  • c++Virtual关键字

    2016-06-26 15:04:05
    c++也是用到面向对象的思想,因此创建函数时,当子类重写了父类函数,则默认会被父类函数方法覆盖,无论子类或父类对象调用,都使用父类方法,因此就会涉及到关键字Virtual。 因此,在父类同名函数前增加关键字...
  • new的对象是谁,其调用virtual函数时,即调用谁 class father { public: virtual void v_pp() { printf("this is virtual father"); } void pp() { printf("this is father"); } }; class child { public...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 97,063
精华内容 38,825
关键字:

virtual关键字的作用