virtual

C++中基类的析构函数为什么用virtual虚析构函数

折月煮酒 提交于 2019-12-07 07:09:38
C++中基类采用virtual虚析构函数是为了防止内存泄露的。 具体来说,如果派生类申请了内存空间,并在其析构函数中对该内存空间进行释放,如果基类采用的非虚析构函数,则删除基类指针指向的派生类对象时,就不会触发动态绑定,因此,只会调用基类的虚构函数,而不会调用该派生类的析构函数。因此,在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。为了防止该情况的发生,C++中基类的析构函数应该采用virtual虚析构函数。 关于动态绑定,简单来说,虚函数是动态绑定的基础,动态绑定是实现运行多态的基础,需要触发动态绑定,需要满足以下两个条件: 只有虚函数才能进行动态绑定,非虚函数不能进行动态绑定。 必须通过基类的引用或指针进行函数的调用。 通过基类指针或基类引用做形参,当实参传入不同的派生类(或基类)的指针或引用,在函数内部触发动态绑定,从而来运行时实现多态的。 示例代码讲解 using namespace std ; class Base { public : ~ Base ( ) { cout << "~Base()" << endl ; } } ; class Derived1 : public Base { public : Derived1 ( ) : name_ ( new string ( "NULL" ) ) { } Derived1 ( const string &

Abstract class : invalid abstract return type for member function ‘virtual…’

扶醉桌前 提交于 2019-12-07 07:07:42
问题 In my program I have such class hierarchy: #include <iostream> #include <cmath> #include <sstream> using namespace std; class aa; class bb; class root { public: virtual ~root() {} virtual root add(const aa& a) const=0; virtual root add(const bb& a) const=0; }; class aa: public root { public: aa() { } aa(const aa& a) { } virtual root add(const aa& a) const { return root(new aa()); } virtual root add(const bb& a) const { return root(new bb()); } }; class bb: public root { public: bb() { } bb

C++虚析构函数及纯虚析构函数

血红的双手。 提交于 2019-12-07 07:02:02
C++中析构函数可以为纯虚吗? 众所周知,在实现多态的过程中,一般将基类的析构函数设为virtual,以便在delete的时候能够多态的链式调用。那么析构函数是否可以设为纯虚呢? class CBase { public: CBase() { printf("CBase()\n"); } virtual ~CBase() = 0; }; 答案是可以,那么这样实现的目的是什么呢?当然是避免实例化。 但因为派生类不可能来实现基类的析构函数,所以基类析构函数虽然可以标为纯虚,但是仍必须实现析构函数,否则派生类无法继承,也无法编译通过。 下面详细讨论: 一. 虚析构函数 我们知道,为了能够正确的调用对象的析构函数,一般要求具有层次结构的顶级类定义其析构函数为虚函数。因为在delete一个抽象类指针时候,必须要通过虚函数找到真正的析构函数。 如: class Base { public: Base(){} virtual ~Base(){} }; class Derived: public Base { public: Derived(){}; ~Derived(){}; } void foo() { Base *pb; pb = new Derived; delete pb; } 这是正确的用法,会发生动态绑定,它会先调用Derived的析构函数,然后是Base的析构函数。

C++虚析构函数、纯虚析构函数

旧城冷巷雨未停 提交于 2019-12-07 07:00:39
转自: http://blog.chinaunix.net/uid-20476365-id-1942463.html 虚析构函数 析构函数的工作方式是:最底层的派生类(most derived class)的析构函数最先被调用,然后调用每一个基类的析构函数。 因为在C++中,当一个派生类对象通过使用一个基类指针删除,而这个基类有一个非虚的析构函数,则结果是未定义的。运行时比较有代表性的后果是对象的派生部分不会被销毁。然而,基类部分很可能已被销毁,这就导致了一个古怪的“部分析构”对象,这是一个泄漏资源。排除这个问题非常简单:给基类一个虚析构函数。于是,删除一个派生类对象的时候就有了你所期望的正确行为。将销毁整个对象,包括全部的派生类部分。 但是,一般如果不做基类的类的析构函数一般不声明为虚函数,因为虚函数的实现要求对象携带额外的信息,这些信息用于在运行时确定该对象应该调用哪一个虚函数。典型情况下,这一信息具有一种被称为 vptr(virtual table pointer,虚函数表指针)的指针的形式。vptr 指向一个被称为 vtbl(virtual table,虚函数表)的函数指针数组,每一个包含虚函数的类都关联到 vtbl。当一个对象调用了虚函数,实际的被调用函数通过下面的步骤确定:找到对象的 vptr 指向的 vtbl,然后在 vtbl 中寻找合适的函数指针

C++中的虚析构函数、纯虚析构函数详解

主宰稳场 提交于 2019-12-07 06:57:41
C++中析构函数可以为纯虚函数吗? 众所周知,在实现多态的过程中,一般将基类的析构函数设为 virtual ,以便在 delete 的时候能够 多态的链式调用 。那么析构函数是否可以设为纯虚呢? class CBase { public : CBase () { printf( "CBase()\n" ); } virtual ~CBase() = 0 ; // 析构函数是纯虚函数 }; 答案是可以,那么这样实现的目的是什么呢?当然是 避免实例化 。 但因为 派生类不可能来实现基类的析构函数 ,所以 基类析构函数虽然可以标为纯虚,但是仍必须实现析构函数,否则派生类无法继承,也无法编译通过 。 下面详细讨论: 虚析构函数 我们知道,为了能够正确的调用对象的析构函数,一般要求具有层次结构的 顶级类 定义其析构函数为虚函数。因为在 delete 一个抽象类指针时候,必须要通过虚函数找到真正的析构函数。 如: class Base { public : Base (){} virtual ~Base(){} }; class Derived: public Base { public : Derived (){}; ~Derived(){}; } void foo() { Base *pb; pb = new Derived; delete pb; } 这是正确的用法,会发生 动态绑定

C++中虚析构函数和纯虚函数的作用

别来无恙 提交于 2019-12-07 06:56:53
一. 虚析构函数 为了能够正确的调用对象的析构函数,一般要求具有层次结构的顶级类定义其析构函数为虚函数。因为在delete一个抽象类指针时候,必须要通过虚函数找到真正的析构函数。 class Base { public : Base (){} virtual ~Base(){} }; class Derived: public Base { public : Derived (){}; ~Derived(){}; } void foo() { Base *pb; pb = new Derived; delete pb; } 这是正确的用法,会发生动态绑定,它会先调用Derived的析构函数,然后是Base的析构函数。 如果析构函数不加virtual,delete pb只会执行Base的析构函数,而不是真正的Derived析构函数。 因为不是virtual函数,所以调用的函数依赖于指向静态类型,即Base。 二. 纯虚析构函数 现在的问题是,我们想把Base做出抽象类,不能直接构造对象,需要在其中定义一个纯虚函数。如果其中没有其他合适的函数,可以把析构函数定义为纯虚的,即将前面的CObject定义改成: class Base { public : Base (){} virtual ~Base()= 0 }; 可是,这段代码不能通过编译,通常是link错误,不能找到~Base(

C++中的虚函数(virtual function)

╄→гoц情女王★ 提交于 2019-12-07 06:56:26
1.简介 虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。假设我们有下面的类层次: class A { public: virtual void foo() { cout << "A::foo() is called" << endl;} }; class B: public A { public: virtual void foo() { cout << "B::foo() is called" << endl;} }; 那么,在使用的时候,我们可以: A * a = new B(); a->foo(); // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的! 这个例子是虚函数的一个典型应用,通过这个例子,也许你就对虚函数有了一些概念。它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。 虚函数只能借助于指针或者引用来达到多态的效果,如果是下面这样的代码,则虽然是虚函数,但它不是多态的: class A { public: virtual void foo(); }; class B: public A { virtual void foo(); };

Force the order of functions in the virtual method table?

被刻印的时光 ゝ 提交于 2019-12-07 05:18:49
问题 How can I control the order of virtual functions in the virtual table? Are they laid out in the same order that they are declared in? When inheriting a class with a virtual table, is the virtual table of the inherited class an extension of the base class, or is an entirely new virtual table created with only the inherited classes virtual functions. (i.e. is the virtual table still at index +0x0 of the class?) 回答1: (a) As far as the standard is concerned, you can't, (in fact you can't even

typecasting with virtual functions

我的梦境 提交于 2019-12-07 02:35:10
问题 In the code below, pC == pA: class A { }; class B : public A { public: int i; }; class C : public B { public: char c; }; int main() { C* pC = new C; A* pA = (A*)pC; return 0; } But when I add a pure virtual function to B and implement it in C, pA != pC: class A { }; class B : public A { public: int i; virtual void Func() = 0; }; class C : public B { public: char c; void Func() {} }; int main() { C* pC = new C; A* pA = (A*)pC; return 0; } Why is pA not equal to pC in this case? Don't they both

virtual properties and lazy loading

淺唱寂寞╮ 提交于 2019-12-07 00:33:24
问题 By definition virtual properties or methods are methods visible to sub classes to be overridden. But, NHibernate for example uses virtual properties to ensure lazy loading. My question is not about NHibernate, but how you could use virtual properties to achieve lazy loading? Are there any hidden behaviors about virtual properties that I don't know? 回答1: The fact that they are declared virtual allows NHibernate to override the property and create a proxy implementation for it - the proxy in