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);编译器报错:

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

继承方式/基类成员类型 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; 
}

报错:

另外,对于派生类的派生类而言,也能在类中访问基类的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;
 }

报错:

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。