精华内容
下载资源
问答
  • 构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数。 抽象类中构造和析构均不能使用纯虚函数。 为什么构造函数不能声明为虚函数呢? 1、构造一个对象的时候,必须知道对象的实际...

    一、构造函数不能声明为虚函数

    为什么构造函数不能声明为虚函数呢?

    1、构造一个对象的时候,必须知道对象的实际类型,而虚函数是在运行期间确定实际类型的。如果构造函数为虚函数,则在构造一个对象时,由于对象还未构造成功,编译器还无法知道对象的实际类型,是该类本身还是派生类。无法确定。

    2、虚函数的执行依赖于虚函数表,而虚函数表是在构造函数中初始化的,即初始化vptr,让它指向虚函数表。如果构造函数为虚函数,则在构造对象期间,虚函数表还没有被初始化,将无法进行。

    二、析构函数可以声明为虚函数,而且有时是必须声明为虚函数。

    虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象时,要使用虚析构函数。

    如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可移植性。

    所以基本的一条是:无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。

    抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。

    只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。

    所以注意如果基类不是虚析构函数的话可能会有以下两点问题:

    1、子类所分配的内存不能被释放
    2、子类中成员变量类所分配的内存也不能被释放,因为子类析构函数没有被调用,其变量的析构函数肯定也没被调用了。

    总之:

    基类指针可以指向派生类的对象(多态性),如果删除该指针delete []p;就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。所以,将析构函数声明为虚函数是十分必要的。

     

     

     

     

     

    展开全文
  • 普通函数只能被重载,不能被重写,因此声明为虚函数没有意义。因为编译器会在编译时绑定函数。 构造函数:只有当调用了构造函数,这个对象才能产生,如果把构造函数写成虚函数,这时候我们的对象就没有办法生成。更...

    哪些函数不能成为虚函数?

    1. 普通函数:普通函数不属于成员函数,是不能被继承的。普通函数只能被重载,不能被重写,因此声明为虚函数没有意义。因为编译器会在编译时绑定函数。
    2. 构造函数:当调用了构造函数才能产生对象,通过对象才能调用虚函数,这显然矛盾。
    3. 静态成员函数:静态成员函数是属于类的,不依赖于对象调用,所以也不能成为虚函数。
    4. 友元函数:友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。
    5. 内联函数:内联函数在编译时就被展开,它不能产生函数符号,所以不能往虚表中存放,自然就不能成为虚函数。

    构造函数不能为虚函数的再解释

    1.虚函数调用是在部分信息下完成工作的机制,允许我们只知道接口而不知道对象的确切类型。 要创建一个对象,你需要知道对象的完整信息。 特别是,你需要知道你想要创建的确切类型。 因此,构造函数不应该被定义为虚函数。

    2.虚函数对应一张虚函数表,这个虚函数表是存储在对象的内存空间的,如果构造函数是虚函数就需要通过虚函数表来调用,可是对象还没有实例化,也就是内存空间还没有,找不到虚函数表,所以构造函数是不能声明为虚函数的。

    析构函数作为虚函数---虚析构

    当子类有在堆上申请空间的操作,那么父类指针在释放时无法调用到子类的析构函数,这时就会造成内存泄漏。

    解决方式:将父类中的析构函数改为虚析构或者纯虚析构。

    虚析构和纯虚析构都可以解决父类指针释放子类对象,都需要有具体的函数实现。

    语法:

    • 虚析构:virtual ~类名(){}
    • 纯虚析构:virtual ~类名() = 0;
                        类名::~类名(){}

    下面一个例子:

    #include<iostream>
    using namespace std;
     
    class Animal {
    public:
    	Animal(){
    		cout << "Animal 构造函数调用!" << endl;
    	}
    	virtual void Speak() = 0;
     
    	/*//析构函数加上virtual关键字,变成虚析构函数
    	virtual ~Animal(){
    		cout << "Animal虚析构函数调用!" << endl;
    	}*/
     
    	virtual ~Animal() = 0; //纯虚析构函数 
    };
     
    Animal::~Animal(){
    	cout << "Animal 纯虚析构函数调用!" << endl;
    }
     
    //和包含普通纯虚函数的类一样,包含了纯虚析构函数的类也是一个抽象类。不能够被实例化。
     
    class Cat : public Animal {
    public:
    	Cat(string name){
    		cout << "Cat构造函数调用!" << endl;
    		m_Name = new string(name);
    	}
    	virtual void Speak(){
    		cout << *m_Name <<  "小猫在说话!" << endl;
    	}
    	~Cat(){
    		cout << "Cat析构函数调用!" << endl;
    		if (this->m_Name != NULL) {
    			delete m_Name;
    			m_Name = NULL;
    		}
    	}
    public:
    	string *m_Name;
    };
     
    int main() {
    	Animal *animal = new Cat("Tom");
    	animal->Speak();
    	delete animal;
    	return 0;
    }

    总结:

    • ​ 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象
    • ​ 如果子类中没有堆区数据,可以不写为虚析构或纯虚析构
    • ​ 拥有纯虚析构函数的类也属于抽象类

     

    展开全文
  • 文章目录1 构造函数不能是虚函数,析构函数可以是虚函数2 构造析构函数调用虚函数不会发生多态3 小结 ...建议在设计类时将析构函数声明为虚函数 编程实验:构造,析构,虚函数 // 41-1.cpp #include<iostream>...

    1 构造函数不能是虚函数,析构函数可以是虚函数

    构造函数不可能成为虚函数

    • 在构造函数执行结束后,虚函数表指针才能被正确的初始化

    析构函数可以成为虚函数

    • 建议在设计类时将析构函数声明为虚函数

    编程实验:构造,析构,虚函数

    // 41-1.cpp
    #include<iostream>
    using namespace std;
    class Base
    {
    public:
        Base()
        {
            cout << "Base()" << endl;
        }
        virtual ~Base()
        {
            cout << "~Base()" << endl;
        }
    };
    class Derived : public Base
    {
    public:
        Derived()
        {
            cout << "Derived()" << endl;
        }
        virtual ~Derived()
        {
            cout << "~Derived()" << endl;
        }
    };
    int main()
    {
        Base* p = new Derived();
        delete p;
        return 0;
    }
    

    父类的指针指向子类的对象,new Derived(); 创建一个子类的对象会调用父类的构造函数和子类的构造函数,p 是父类的指针,如果析构函数不是虚函数,会调用父类的析构函数,不会调用子类的构造函数。
    将析构函数定义为虚函数,根据多态属性,析构指向的对象,则析构子类 Derived,就会先调用子类析构函数,再调用父类析构函数。

    编译运行:

    $ g++ 41-1.cpp -o 41-1
    $ ./41-1
    Base()
    Derived()
    ~Derived()
    ~Base()
    

    2 构造析构函数调用虚函数不会发生多态

    构造函数中不会发生多态行为

    • 在构造函数执行时,虚函数表指针未被正确初始化

    析构函数中不会发生多态行为

    • 在析构函数执行时,虚函数表指针已经被销毁

    所以,构造函数和析构函数中不发生多态行为,只调用当前类中定义的函数版本!!!

    // 41-2.cpp
    #include<iostream>
    using namespace std;
    class Base
    {
    public:
        Base()
        {
            cout << "Base()" << endl;
            func();								// 调用虚函数
        }
        virtual void func()						// 增加虚函数
        {
            cout << "Base::func()" << endl;
        }
        virtual ~Base()
        {
            func();								// 调用虚函数
            cout << "~Base()" << endl;
        }
    };
    class Derived : public Base
    {
    public:
        Derived()
        {
            cout << "Derived()" << endl;
            func();								// 调用虚函数
        }
        virtual void func()						// 增加虚函数
        {
            cout << "Derived::func()" << endl;
        }
        virtual ~Derived()
        {
            func();								// 调用虚函数
            cout << "~Derived()" << endl;
        }
    };
    int main()
    {
        Base* p = new Derived();
        delete p;
        return 0;
    }
    

    编译运行,构造函数和析构函数中不发生多态行为,只调用当前类中定义的函数版本

    $ g++ 41-2.cpp -o 41-2
    $ ./41-2
    Base()
    Base::func()
    Derived()
    Derived::func()
    Derived::func()
    ~Derived()
    Base::func()
    ~Base()
    

    3 小结

    1、构造函数不能成为虚函数,析构函数可以成为虚函数
    2、构造函数和析构函数中都无法产生多态

    展开全文
  • 静态函数可以分为全局静态函数和类的静态成员函数。 Static关键字 在类中,用static声明的成员变量静态成员变量,它该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份...

    静态函数
    用static声明的函数是静态函数。静态函数可以分为全局静态函数类的静态成员函数

    Static关键字
    在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化对于该类的所有对象来说,static成员变量只有一份
    用static声明的方法是静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。
    静态方法不再是针对于某个对象调用,所以不能访问非静态成员。

    可以通过对象引用或类名(不需要实例化)访问静态成员

    C++类静态数据成员与类静态成员函数
    函数调用的结果不会访问或者修改任何对象(非static)数据成员
    ,这样的成员声明为静态成员函数比较好。且如果static int func(....)不是出现在类中,则它不是一个静态成员函数,只是一个普通的全局函数,只不过由于static的限制,它只能在文件所在的编译单位内使用,不能在其它编译单位内使用。
    静态成员函数的声明除了在类体的函数声明前加上关键字static,以及不能声明为const或者volatile之外,与非静态成员函数相同。出现在类体之外的函数定义不能制定关键字static。
    静态成员函数没有this指针

    在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢?

    这个问题便是本章的重点:声明为static的类成员或者成员函数便能在类的范围内共同享我们把这样的成员称做静态成员和静态成员函数。

    下面我们用几个实例来说明这个问题,类的成员需要保护,通常情况下为了不违背类的封装特性,我们是把类成员设置为protected(保护状态)的,但是我们为了简化代码,使要说明的问题更为直观,更容易理解,我们在此处都设置为public。

    以下程序我们来做一个模拟访问的例子,在程序中,每建立一个对象我们设置的类静态成员变自动加一,代码如下:

    1. #include <iostream>  
    2. using namespace std;  
    3.   
    4. class Internet  
    5. {  
    6. public:  
    7.      Internet(char *name,char *address)  
    8.      {  
    9.          strcpy(Internet::name,name);  
    10.          strcpy(Internet::address,address);  
    11.          count++;  
    12.      }   
    13.   
    14.      static void Internet::Sc()//静态成员函数  
    15.      {  
    16.          cout<<count<<endl;  
    17.      }  
    18.   
    19.      Internet &Rq();   
    20.   
    21. public:  
    22.      char name[20];  
    23.      char address[20];  
    24.      static int count;//这里如果写成static int count=0;就是错误的  
    25. };  
    26.   
    27. Internet& Internet::Rq()//返回引用的成员函数  
    28. {  
    29.      return *this;  
    30. }  
    31.   
    32. int Internet::count = 0;//静态成员的初始化  
    33.   
    34. void vist()  
    35. {  
    36.      Internet a1("中国软件开发实验室","www.cndev-lab.com");  
    37.      Internet a2("中国软件开发实验室","www.cndev-lab.com");  
    38. }   
    39.   
    40. void fn(Internet &s)  
    41. {  
    42.      cout<<s.Rq().count;  
    43. }  
    44.   
    45. void main()  
    46. {  
    47.      cout<<Internet::count<<endl;//静态成员值的输出  
    48.      vist();  
    49.      Internet::Sc();//静态成员函数的调用  
    50.      Internet b("中国软件开发实验室","www.cndev-lab.com");  
    51.      Internet::Sc();  
    52.      fn(b);  
    53.      cin.get();  
    54. }  



    上面代码我们用了几种常用的方式建立对象,当建立新对象并调用其构造函数的时候,静态成员cout便运行加1操作,静态成员的初始化应该在主函数调用之前,并且不能在类的声明中出现,通过运行过程的观察我们发现,静态成员count的状态并不会随着一个新的对象的新建而重新定义,尽而我们了解到类的静态成员是属于类的而不是属于哪一个对象的,所以静态成员的使用应该是类名称加域区分符加成员名称的,在上面的代码中就是Internet::count,虽然我们仍然可以使用对象名加点操作符号加成员名称的方式使用,但是不推荐的,静态类成员的特性就是属于类而不专属于某一个对象。

    静态成员函数的特性类似于静态成员的使用,同样与对象无关,调用方法为类名称加域区分符加成员函数名称,在上面的代码中就是Internet::Sc();静态成员函数由于与对象无关系,所以在其中是不能对类的普通成员进行直接操作的。

    如果上面的 static void Internet::Sc()修改成为:

    1. static void Internet::Sc()//静态成员函数  
    2. {  
    3.     cout<<name<<endl;//错误  
    4.      cout<<count<<endl;  
    5. }  



    静态成员函数与普通成员函数的差别就在于缺少this指针,没有这个this指针自然也就无从知道name是哪一个对象的成员了。

    根据类静态成员的特性我们可以简单归纳出几点,静态成员的使用范围:
    1.用来保存对象的个数。
    2.作为一个标记,标记一些动作是否发生,比如:文件的打开状态,打印机的使用状态,等等。
    3.存储链表的第一个或者最后一个成员的内存地址。

    为了做一些必要的练习,深入的掌握静态对象的存在的意义,我们以前面的结构体的教程为基础,用类的方式描述一个线性链表,用于存储若干学生的姓名,代码如下:

    1. #include <iostream>  
    2. using namespace std;  
    3.   
    4. class Student  
    5. {  
    6. public:  
    7.      Student (char *name);  
    8.      ~Student();  
    9.   
    10. public:  
    11.      char name[30];  
    12.      Student *next;  
    13.      static Student *point;  
    14. };  
    15.   
    16. Student::Student(char *name)  
    17. {  
    18.      strcpy(Student::name,name);  
    19.      this->next=point;  
    20.      point=this;  
    21. }  
    22.   
    23. Student::~Student ()//析构过程就是节点的脱离过程  
    24. {  
    25.      cout<<"析构:"<<name<<endl;  
    26.   
    27.      if(point==this)  
    28.      {  
    29.          point=this->next;  
    30.          cin.get();  
    31.          return;  
    32.      }  
    33.   
    34.      for(Student *ps=point;ps;ps=ps->next)  
    35.      {  
    36.          if(ps->next==this)  
    37.          {  
    38.          cout<<ps->next<<""<<this->next<<endl;  
    39.          ps->next=next;//=next也可以写成this->next;  
    40.          cin.get();  
    41.          return;  
    42.          }  
    43.      }  
    44.   
    45.      cin.get();  
    46. }  
    47.   
    48. Student* Student::point=NULL;  
    49. void main()  
    50. {  
    51.      Student *c = new Student("marry");  
    52.      Student a("colin");  
    53.      Student b("jamesji");  
    54.      delete c;  
    55.      Student *fp=Student::point;  
    56.      while(fp!=NULL)  
    57.      {  
    58.          cout<<fp->name<<endl;  
    59.          fp=fp->next;  
    60.      }  
    61.   
    62.      cin.get();  
    63. }   
    64.   
    65.   
    66. <span style="font-size:14px;">从上面的代码来看,原来单纯结构化编程需要的一个链表进入全局指针在这里被类的静态成员指针所替代(类的静态成员完全可以替代全局变量),这个例子的理解重点主要是要注意观察类成员的析构顺序,通过对析构顺序的理解,使用析构函数来进行节点的脱链操作。  
    67.   
    68. <strong><span style="color:maroon;">为什么虚函数必须是非静态成员函数</span></strong>  
    69. 如果定义为虚函数,那么它就是动态绑定的,也就是在派生类中可以被覆盖的,这与静态成员函数的定义本身就是相矛盾的。  
    70.   
    71. ==  
    72. 主要有两个作用:   
    73.      1、管理静态数据成员;   
    74.      2、提供类范围的功能,即不需要对象来实现的功能。   
    75. <strong><span style="color:red;">比如Symbian</span>中的NewL/LC方法就是static的</strong>  
    76.   
    77. ==  
    78. 使用static关键字声明的函数成员是静态的,静态成员函数同样也属于整个类,由同一个类的所有对象共同维护,为这些对象所共享。  
    79.   
    80. 作为成员函数,它的访问属性可以受到类的严格控制,对于公有的静态函数成员函数,可以通过类名或对象名来调用,但一般情况下建议用对象名来引用静态函数成员<strong><span style="color:blue;">(真的吗?)</span></strong>。注意,一般的成员函数只能通过对象名来调用。  
    81. 由于一个类的静态成员函数只有一个拷贝,因此它访问对象的数据何函数使受到了限制。静态成员函数可以直接访问该类的静态数据成员。而<strong>访问非静态数据成员,必须通过参数传递方式得到对象名,然后通过对象名来访问</strong>。可以看到,通过静态函数成员访问非静态成员使相当麻烦的,一般的使用中,它主要用来访问全局变量或同一个类中的静态数据成员,特别是和后者一起使用,达到对同一个类中对象之间共享的数据进行维护的目的。  
    82. <strong><span style="color:red;">构造函数不可以定义为static</span>,</strong>看了上面,应该可以理解原因。  
    83.   
    84. 注意,由于static不是函数类型中的一部分,所以在类定义之外定义静态成员函数时不使用static,在类中定义的静态成员函数是内联的。  
    85.   
    86. 一般来说,通过成员名限定比使用对象名访问静态成员要好。因为静态成员不是对象的成员。  
    87.   
    88. <strong><span style="color:red;">静态成员可以被继承</span></strong>,这时,基类对象和派生类的对象共享该静态成员,除此之外,在类等级中对静态成员的其他特性(例如,静态成员在派生类中的访问权限,在派生类中重载成员函数等)的分析与一般成员类似。  
    89.   
    90. <strong><span style="color:red;">静态成员函数不能被申明为虚函数</span></strong>,静态成员具有外部连接属性,static仅有的含义是使该成员为该类的所有对象共享。  
    91.   
    92. <strong>类中的任何成员函数都可以访问静态成员,但静态成员函数只能通过对象名(或指向对象的指针)访问该对象的非静态成员,因为静态成员函数没有this 指针。</strong></span><strong>  
    93.   
    94. <span style="color:#339966;">  
    95. </span><strong><span style="font-size:14px;color:#ff6600;">虚函数必须是非静态成员函数</span></strong></strong><span style="color:#ff6600;">  
    96. </span><strong><span style="font-size:14px;color:#ff6600;">构造函数不可以定义为static</span></strong>  
    为什么虚函数必须是非静态成员函数 构造函数能为static吗?

    转载于:https://www.cnblogs.com/qianggezhishen/p/7349496.html

    展开全文
  • 静态函数可以分为全局静态函数和类的静态成员函数。 <br />Static关键字 在类中,用static声明的成员变量静态成员变量,它该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static...
  • 可否想过,构造函数和析构虚函数可以声明为虚函数吗?答案是,构造函数不能声明为虚函数,而析构函数可以声明为虚函数。 虚函数表指针的初始化是发生在构造函数完成之后的,因此,把构造函数编译为虚函数是无意义的...
  • C++ 虚函数

    2015-09-01 17:07:00
    3、析构函数可以定义成虚函数吗? 可以,虚析构函数是允许的,但是要注意,只有在作为基类时,我们才需要将析构函数写成虚函数。 4、虚拟机制与构造函数 在类的构造函数中,虚拟机制不会发生作用。因为,基类的构造...
  • 这点我很不能理解,讲道理说,虽然我MAIN.EXE中的CBase被我声明成了导入的,但是,baseObj调用的构造函数实实在在MAIN.EXE中的CBase的构造函数,那啥vptr所指向表却是Test.DLL中的呢?通过调试模块查看各模块的...
  • C++ virtual关键字

    千次阅读 多人点赞 2017-08-14 19:25:02
    之前始终没有搞清楚C++中 “virtual” 关键字的用法。...静态函数可以声明为虚函数吗 构造函数可以为虚函数吗 析构函数可以为虚函数吗 虚函数可以为私有函数吗 虚函数可以被内联吗 纯虚函数与抽象类
  • 静态函数

    2011-11-04 00:44:56
    什么虚函数必须是非静态成员函数 构造函数static吗? 作者:肥仔 来源:C++博客 发布时间:2009-08-19 13:25 阅读:260 次 原文链接 [收藏]  静态函数 用static声明的函数是静态函数。静态函数可以...
  • C++高频知识总结P4

    2020-09-03 15:34:49
    构造函数可以虚函数吗?析构函数可以是虚函数吗?为什么析构函数要定义为虚函数?2.构造函数或者析构函数中调用虚函数会怎样?3.声明和定义的区别?4.指针函数和函数指针?5.指针常量?常量指针?6.深拷贝与浅拷贝...
  • 1,静态成员函数可以声明为虚函数吗? 2,派生类构造函数对基类构造函数的调用顺序就是基类构造函数的执行顺序,这句话错在了哪里?真相是什么样的?
  • 18多态

    2017-06-01 14:10:52
    多态多态 问题引出 解决方案 工程意义 成立条件 理论基础 本质剖析 1 多态实现原理 ...6 类的每个成员函数是否都可以声明为虚函数为什么 7 构造函数中调用虚函数能实现多态吗为什么 8 虚函数表指针VPTR被编译
  • 多态原理探究&&------

    2018-08-04 16:07:00
    2.在构造函数中调用虚函数能实现多态吗? 2)实现原理 ...3.是否可以将类中的每个成员函数都声明成虚函数?...故:出于效率考虑,没有必要将所有成员函数都声明为虚函数。 4.如何证明vptr指针...
  • C#面经_全职

    2021-06-11 23:17:00
    8、析构函数可以被定义为虚函数吗? 9、构造函数的作用? 10、用过或了解的设计模式? 11、web如何获取客户端的数据? 12、程序崩溃或异常怎么处理? 13、内存中不是非托管内存崩溃了,调用第三方库导致内存崩溃
  • 零起点学通C++多媒体范例教学代码

    热门讨论 2010-11-30 09:35:13
    11.10.2 通过构造函数将变量转换一个对象的成员变量 11.10.3 通过operator关键字进行转换 11.11什么可以重载,什么不可以重载 第12章 继承 12.1 什么是继承和派生 12.1.1 复杂的继承和派生 12.1.2 继承和派生如何...
  • 11.10.2 通过构造函数将变量转换一个对象的成员变量 11.10.3 通过operator关键字进行转换 11.11什么可以重载,什么不可以重载 第12章 继承 12.1 什么是继承和派生 12.1.1 复杂的继承和派生 12.1.2 继承和...
  • 11.10.2 通过构造函数将变量转换一个对象的成员变量 179 11.10.3 通过operator关键字进行转换 181 11.11 什么可以被重载,什么不可以 182 第12章 继承 183 12.1 什么是继承和派生 183 12.1.1 复杂的继承和...
  • 10.3.1 声明和定义构造函数 10.3.2 使用构造函数 10.3.3 默认构造函数 10.3.4 析构函数 10.3.5 改进Stock类 10.3.6 构造函数和析构函数小结 10.4 this指针 10.5 对象数组 10.6 类作用域 10.6.1 作用域类...
  • MFC的程序框架剖析

    2015-03-05 09:53:19
    C:在CTestView类中,通过GetParent函数可以获得CMainFrame框架窗口对象的指针 D:实现一(在视类窗口中通过ShowWindow函数显示按钮) int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... m_btn.Create...
  • “,然后再再深入一点,“如果把析构函数标记为虚函数呢?”,要准确得出这些答案就得考查我们深厚的内力了。其实,我还是蛮喜欢这样写书风格的,层层深入,很能考查读者对某个知识点的掌握程度,然后再跟着作者再往...
  • 21天学通C++ (中文第五版)

    热门讨论 2010-06-23 16:57:03
    12.5.1 虚函数的工作原理 12.5.2 通过基类指针访问派生类的方法 12.5.3 切除 12.5.4 创建虚析构函数 12.5.5 虚复制构造函数 12.5.6 使用虚方法的代价 12.6 小结 12.7 问与答 12.8 作业 12.8.1 测验 12.8.2...
  • 面试题209 基类中有一个虚函数,子类还需要申明virtual吗 面试题210 C++的类有什么优点 面试题211 如何实现多态?父类和子类的继承关系如何 面试题212 什么要引入抽象基类和纯虚函数(摩托罗拉笔试 题) 面试题...
  • 2-5 请写出C++语句声明一个常量PI,值3.1416;再声明一个浮点型变量a,把PI的值赋给a。 解: const float PI = 3.1416; float a = PI; 2-6 在下面的枚举类型中,Blue的值是多少? enum COLOR { WHITE, BLACK = ...

空空如也

空空如也

1 2 3
收藏数 46
精华内容 18
关键字:

构造函数可以声明为虚函数吗