继承与virtual

来源:互联网 发布:sql视图数据会重复 编辑:程序博客网 时间:2024/04/29 17:17

继承与virtual

 

子类与父类间关系:

1.   覆盖

2.   重载

 

正常情况下,继承其实就是将父类的代码镶入子类,只是这个动作有编译器完成,因此,子类中期是存在父类的副本。通过将子类对象转为父类,就可以直接访问子类中的父类的函数和数据。其实就是嵌套类。而虚函数则是使用了虚函数表,也就是指针,因此不存在父类的相应函数的副本。

不过friend,static不能继承,private函数和数据没有嵌入。

1.只有virtual的函数在使用在使用指针的情况下才能实现覆盖。如果是 子类对象转化为父类对象(不是指针对象),不存在覆盖的问题。

2.如果没有明确的理由,因将所有函数写成virtual,构造函数除外。析构函数必须是virtual。为了明确虚函数,必须将子类父类中都用上virtual。不过c++规则是只要父类函数是virtal,他派生的所有孙子都是virtual

3.对于继承体系中函数的默认值,永远都是采用父类的,不管子类的默认值如何,所以如果父类函数的参数声明了默认值,这子类中覆盖父类的函数,他的默认值将永远用父类的,不论指针对象与否。

4.重载时,返回类型可以不同,这个仅局限在子类的函数的返回值类型与父类函数返回值类型间是继承关系

5.如果子类重载父类的函数但没有覆盖父类函数,则子类不能直接调用父类定义的那个函数,无论该父类是什么;

如:

#include <iostream>

#include <string>

 

using namespace std;

 

class Test

{

public:

     char* str;

     int a;

     Test(){a=5;str=NULL;};

     Test(const char*str1)

     {

         a=6;

         //str = str1;

         this->str = new char[strlen(str1)+1];

         strcpy(str, str1);

     };

 

     Test& operator=(const Test& t)

     {

         a=t.a;

         char* str1 = t.str ;

         this->str = new char[strlen(str1)+1];

         strcpy(str, str1);

     };

     Test(const Test& t)

     {

         this->str = t.str;

     };

     int getAdd()

         //测试返回的类型是不是const还是临时变量

     {

         return a;

     };

     int getAdd(std::string str){return 1;}

     virtual int getVirtual(){return 1;};

     friend Test& getThis(Test& t){return t;}

};

 

class subTest:public Test

{

public:

     int getAdd(int a)  {return a;};

     virtual int getVirtual(int a){return a;};

//   using Test::getAdd;

//   using Test::getVirtual;

//   int getAdd(){return 1;};

};

 

int main(void)

{   

     Test t("abcd");

     Test t1 = getThis(t);

     t1.a = 66;

     t1.str = "adf";

     cout << t.str << "/t" << t1.str << endl << t1.a<<" /t" << t.a << endl;

    

     subTest st ;

     subTest *pst = new subTest();

     pst->getVirtual();     //错误,除非使用了using Test::getAdd;明确要继承该方法

     pst->getAdd();         //错误

     st.getVirtual();       //错误

     st.getAdd();       //错误

     st.getAdd(std::string("dfdf"));      //错误

     Test t11 = t;

     t11.getAdd();

     t11.getVirtual();

     Test *pt2 = pst;

     pt2->getAdd();

     pt2->getVirtual();

     return 1;

}

 

 6.子类的成员函数不能调用父类的private函数和数据

7.访问级别的僭越。如果一个虚函数在父类中是public,而子类中覆盖时是private。那么子类的这个函数还是可以访问的,只是访问技巧变了,得用指针才行,如下

#include <iostream>

#include <string>

 

using namespace std;

class Test

{

public:

     virtual void add(){cout<< "Test" << endl;};

};

 

class subTest:public Test

{

private:

     void add(){cout << "subTest" << endl;};

 

};

 

int main(void)

{

     Test t,*pt;

     Test st,*pst;

     pt = new subTest();

     pt->add();

     t = st;       //调用的是subTest::add();

     t.add();      //调用的是父类的

     return 1;

}