C++继承

C++继承可以是单一继承或多重继承,每一个继承连接可以是public,protected,private也可以是virtual或non-virtual。然后是各个成员函数选项可以是virtual或non-virtual或pure virtual。本文仅仅作出一些关键点的验证。

  public继承,例如下:

class base

{

......

};

class derived:public base  //子类

{

......

};

如果这样写,编译器会理解成类型为derived的对象同时也是类型为base的对象,但类型为base的对象不是类型为derived的对象(金鱼是鱼,但是是鱼的不一定就是金鱼)。这点很重要。那么函数形参为base类型适用于derived,形参为derived不适用于base。下面是验证代码,一个参数为base的函数,传入derived应该成功执行,相反,一个参数为derived的函数

#include <iostream>

#include <stdio.h>

#include <string>

class base

{

public:

    base()//无参构造函数

        :baseName(""),baseData(0)//成员初始化

    {}

    base(std::string bn,int bd)//带参构造函数

        :baseName(bn),baseData(bd) //成员初始化

    {}



    std::string getBaseName() const

    {

        return baseName;

    }



    int getBaseData()const

    {

        return baseData;

    }



private:

    std::string baseName;

    int baseData;

};



class derived:public base  //子类

{

public:

    derived():base(),derivedName("")

    {}

    derived(std::string bn,int bd,std::string dn)

        :base(bn,bd),derivedName(dn) //子类构造函数中显示调用父类的构造函数

    {}

    std::string getDerivedName() const

    {

        return derivedName;

    }

private:

    std::string derivedName;

};



void show(std::string& info,const derived& b)

{

    info.append("Name is ");

    info.append(b.getBaseName());

    info.append(", baseData is ");

    char buffer[10];

    sprintf_s(buffer,"%d",b.getBaseData());//VS2012用sprintf报错

    info.append(buffer);

}

int main(int argc,char* argv[])

{

    base b("test",10);

    std::string s;

    show(s,b);

    std::cout<<s<<std::endl;    

    derived d("btest",5,"dtest");

    std::string ss;

    show(ss,d);

    std::cout<<ss<<std::endl;

    return 0;

}

运行结果为:

Name is test, baseData is 10
Name is btest, baseData is 5
请按任意键继续. . .

下面改改代码,将show()函数参数变为derived

void show(std::string& info,const derived& b)

{

    info.append("Name is ");

    info.append(b.getBaseName());

    info.append(", baseData is ");

    char buffer[10];

    sprintf_s(buffer,"%d",b.getBaseData());//VS2012用sprintf报错

    info.append(buffer);

}

调用show(s,d);编译器报错:

image

第二点对各种形式的继承作出验证,首先给出表格

继承方式/基类成员类型 public protected private
public public protected 无法继承
protected protected protected 无法继承
private private private 无法继承

这里解释一下,这里仅仅表达基类的成员,被public,protected,private三种方式继承后,在原基类为public,protectedc,private的成员在继承类里类型为表格里内容

注意两点:

1.对于基类的protected成员,只有在派生类中才可以通过派生类对象访问基类的protected成员。这里说的是在派生类,不是说派生类对象。也就是说只能在派生类的内部访问,不能用派生类对象去访问基类的protected成员。

2.表格中的private成员,基类的private成员可以被子类继承下来,只是派生类不能访问。有人会说这样继承下来是不是没有意义呢,还浪费内存空间。不是,虽然不能直接访问,但是如果基类如果提供了接口,就可以通过这个接口来访问了。

#include<iostream>

#include<string>

class base

{

public:

    std::string testPublic()

    {

        return std::string("this is public base");

    }

protected:

    std::string testProtected()

    {

        return std::string("this is protected base");

    }

private:

    std::string testPrivate()

    {

        return std::string("this is private base");

    }

};

class derivedPublic:public base

{

public:

    std::string testPubPublic()

    {

        return testPublic()+= "in derived";

    }



    std::string testProPublic()

    {    

        return testProtected()+= "in derived";

    }



    std::string testPriPublic()                   

    {    

        return testPrivate()+= "in derived";

    }

};



int main(int argc,char* argv[])

{

    derivedPublic dpub;

std::cout << dpub.testPublic() << std::endl; 

}

报错:

image

另外,对于派生类的派生类而言,也能在类中访问基类的protected成员,它的对象就不能,跟派生类一样。

#include <iostream>

#include <string>

 

 class base

 {

     public:

         std::string testPublic()

         {

             return std::string("this is public base");

         }

     protected:

         std::string testProtected()

         {

             return std::string("this is protected base");

         }

     private:

         std::string testPrivate()

         {

             return std::string("this is private base");

         }

 }; 

 class derivedPublic:public base

 {

     public:

         std::string testPubPublic()

         {

             return testPublic()+= "in derived";

         }         

         std::string testProPublic()

         {    

             return testProtected()+= "in derived";

         }         

 //        std::string testPriPublic()                   

 //        {    

 //            return testPrivate()+= "in derived";

 //        }

 }; 

 class deepDerived:public derivedPublic

 {

     public:

         std::string deepProtected()

         {

             return testProtected() +="in deep";

         }         

         std::string deepPublic()

         {

             return testPublic() +="indeep";

         }

 }; 

 int main(int argc,char* argv[])

 {

     derivedPublic dpub;

     std::cout << dpub.testProtected() << std::endl; 

     deepDerived deepdpub;

     std::cout<<deepdpub.testPublic() <<std::endl;

     std::cout<<deepdpub.testProtected() <<std::endl;

     std::cout<<deepdpub.deepProtected() <<std::endl;

     std::cout<<deepdpub.deepPublic() <<std::endl;

 }

报错:

image

你可能感兴趣的:(C++)