C++继承介绍

然后是各个成员函数选项可以是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>

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 base& b)
 {
     info.append("Name is ");
     info.append(b.getBaseName());
     info.append(", baseData is ");
     char buffer[10];
     sprintf(buffer,"%d",b.getBaseData());
         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;
 }

运行结果为:

base:baseName is test, baseData is 10
base:baseName is btest, baseData is 5

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


代码如下:

void show2(std::string& info,const derived& d)
{
    info.append("Name is ");
    info.append(d.getBaseName());
    info.append(", baseData is ");
    char buffer[10];
    sprintf(buffer,"%d",d.getBaseData());
    info.append(buffer);
}

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


代码如下:

derived_class.cpp: In function `int main(int, char**)':
 derived_class.cpp:84: error: invalid initialization of reference of type 'const derived&' from expression of type 'base'
 derived_class.cpp:70: error: in passing argument 2 of `void show2(std::string&, const derived&)'第二点对各种形式的继承作出验证,首先给出表格






















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


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


代码如下:

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;

报下面错误,说明testPrivate()不是derived私有函数而是base的私有函数
derived11.cpp:16: error: `std::string base::testPrivate()' is private
derived11.cpp:36: error: within this context这样验证private类型成员无法被继承(public,private,protected)注:private,protected略去不做证明
下面只要验证 testProtected 能被第三层继承类继承,但是无法被第三层类直接调用就说明是public继承后继承类型为protected,而基类为Public类型成员则即可被继承又可以直接调用。


代码如下:

#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;
}

这里服务器报错

derived12.cpp:13: error: `std::string base::testProtected()' is protected
derived12.cpp:62: error: within this context这样就验证了一个是public,一个是protected,protected是不能直接调用的,但是被继承后是可以被public成员调用的。
下面的已经证明,详细步骤就略去如果对该部分验证感兴趣,可以看下面代码。


代码如下:

#include <iostream>
 2 #include <string>
 3 class base
 4 {
 5     public:
 6         std::string testPublic()
 7         {
 8             return std::string("this is public base");
 9         }
     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 test()
         {
             return testPublic() +="in 3";
         }
 };

class derivedProtected:protected base
 {
     public:
         std::string testPubProtected()
         {
             return testPublic()+= "in derived";
         }

std::string testProProtected()
         {   
             return testProtected()+= "in derived";
         }
 };

class deepDerived2:public derivedProtected
 {
     public:
         std::string test()
         {
             return testPublic() +="in 3";
         }
 };

class derivedPrivate:private base
 {
     public:
         std::string testPubPirvate()
         {
             return testPublic()+= "in derived";
         }

std::string testProPrivate()
         {   
             return testProtected()+= "in derived";
         }

};

//class deepDerived3:public derivedPrivate
 //{
 //    public:
 //        std::string test()
 //        {
 //            return testPublic() +="in 3";
 //        }
 //};

int main(int argc,char* argv[])
 {
     derivedPublic dpub;
    //derivedProtected dpro;
    //derivedPrivate dpri;
    std::cout<<dpub.testPublic()<<std::endl;       //
    //std::cout<<dpub.testProtected()<<std::endl;    //用户被继承也是无法使用
    //cout<<dpub.testPrivate()<<std::endl;         //基类都是私有函数
    std::cout<<dpub.testPubPublic()<<std::endl;
    std::cout<<dpub.testProPublic()<<std::endl;
    //std::cout<<dpub.testPriPrivate()<<std::endl; //没有被继承

deepDerived dd;
    std::cout<<dd.test()<<std::endl;

derivedProtected dpro;
    //std::cout<<dpro.testPublic()<<std::endl;        //变成protected类型
    std::cout<<dpro.testPubProtected()<<std::endl;
    std::cout<<dpro.testProProtected()<<std::endl;

deepDerived2 dd2;
    std::cout<<dd2.test()<<std::endl;

derivedPrivate dpri;
    std::cout<<dpri.testPubPirvate()<<std::endl;
    std::cout<<dpri.testProPrivate()<<std::endl;

//    deepDerived3 dd3;
//    std::cout<<dd3.test()<<std::endl;

(0)

相关推荐

  • C++继承中的访问控制实例分析

    本文较为深入的探讨了C++继承中的访问控制,对深入掌握C++面向对象程序设计是非常必要的.具体内容如下: 通常来说,我们认为一个类有两种不同的用户:普通用户 和 类的实现者.其中,普通用户编写的代码使用类的对象,这部分代码只能访问类的公有(接口)成员:实现者则负责编写类的成员和友元的代码,成员和友元既能访问类的公有部分,也能访问类的私有部分.如果进一步考虑继承的话就会出现第三种用户,即派生类.派生类可以访问基类的公有(public)成员和受保护(protected)成员,但不能访问基类的私有(p

  • C++ 中继承与动态内存分配的详解

    C++ 中继承与动态内存分配的详解 继承是怎样与动态内存分配进行互动的呢?例如,如果基类使用动态内存分配,并重新定义赋值和复制构造函数,这将怎样影响派生类的实现呢?这个问题的答案取决于派生类的属性.如果派生类也使用动态内存分配,那么就需要学习几个新的小技巧.下面来看看这两种情况: 一.派生类不使用new 派生类是否需要为显示定义析构函数,复制构造函数和赋值操作符呢? 不需要! 首先,来看是否需要析构函数,如果没有定义析构函数,编译器将定义一个不执行任何操作的默认构造函数.实际上,派生类的默认构造

  • 深入解析C++中类的多重继承

    C++类的多继承 在前面的例子中,派生类都只有一个基类,称为单继承.除此之外,C++也支持多继承,即一个派生类可以有两个或多个基类. 多继承容易让代码逻辑复杂.思路混乱,一直备受争议,中小型项目中较少使用,后来的 Java.C#.PHP 等干脆取消了多继承.想快速学习C++的读者可以不必细读. 多继承的语法也很简单,将多个基类用逗号隔开即可.例如已声明了类A.类B和类C,那么可以这样来声明派生类D: class D: public A, private B, protected C{ //类D新

  • 详解C++中实现继承string类的MyString类的步骤

    昨天师兄又出了道测试题,让我们实现类似于string类的没有MyString类,刚开始很头疼,可是真正在自己写代码的时候又很兴奋的发现,这个过程真的是个很宝贵的机会,让我又有机会可以很好的熟悉回顾C++的很多知识-类设计,构造析构函数,成员函数,友元函数,引用,重载,字符串操作,动态内存分布.....于是昨天花了半天时间写了300多行代码,并认真的进行了相关测试.修改和总结.因为内容有点丰富,所以想分几次写出来,条理也清楚些. 类的空间分配:类给它的每个对象都分配了独立的空间去存储它的数据成员,

  • C++ 多重继承和虚拟继承对象模型、效率分析

    一.多态 C++多态通过继承和动态绑定实现.继承是一种代码或者功能的传承共享,从语言的角度它是外在的.形式上的,极易理解.而动态绑定则是从语言的底层实现保证了多态的发生--在运行期根据基类指针或者引用指向的真实对象类型确定调用的虚函数功能!通过带有虚函数的单一继承我们可以清楚的理解继承的概念.对象模型的分布机制以及动态绑定的发生,即可以完全彻底地理解多态的思想.为了支持多态,语言实现必须在时间和空间上付出额外的代价(毕竟没有免费的晚餐,更何况编译器是毫无感情): 1.类实现时增加了virtual

  • C++多重继承与虚继承分析

    本文以实例形式较为全面的讲述了C++的多重继承与虚继承,是大家深入学习C++面向对象程序设计所必须要掌握的知识点,具体内容如下: 一.多重继承 我们知道,在单继承中,派生类的对象中包含了基类部分 和 派生类自定义部分.同样的,在多重继承(multiple inheritance)关系中,派生类的对象包含了每个基类的子对象和自定义成员的子对象.下面是一个多重继承关系图: class A{ /* */ }; class B{ /* */ }; class C : public A { /* */ }

  • C++多继承同名隐藏实例详细介绍

    如果某个派生类的部分或者全部直接基类是从另一个共同的基类派生而来,在这些俄直接基类中, 从上一级基类继承来的成员就拥有相同的名称,因此派生类中就会出现同名现象.对这种类型的同名成员也要使用作用域分辨符来唯一标识,而且必须使用直接基类来进行限定. -------------------------------------------------- /* * File: main.cpp * Author: yubao * * Created on May 31, 2009, 8:54 AM */

  • C++中virtual继承的深入理解

    今天专门看了一下虚继承的东西,以前都没怎么用过,具体如下:父类:  复制代码 代码如下: class   CParent { .... }; 继承类的声明比较特别: class   CChild   :   virtual   public   CParent { .... } 请问,这个"virtual"是什么作用及含义? --------------------------------------------------------------- 表示虚拟继承,和普通继承是C++的

  • Java面向对象之类的继承介绍

    目录 继承的作用 如果没有继承机制是怎么样的? 使用继承机制后的示例? 类的继承是什么? 子类和父类的继承机制 Java单继承 Java继承的顶级父类:Object 对象的类型转换 对象向上转型 对象向下转型 总结 继承的作用 如果没有继承机制是怎么样的? 有以下两个类,分别是Student.Teacher,它们的实现类如下: /** * 老师类 封装了姓名.年龄 * * @author Administrator * */ public class Teacher { private Stri

  • javascript 原型继承介绍

    暑假还搞了ext4的web desktop,更多的也是javascript的东西.对于javascript,以前就只会document.getElementById()和alert(),现在才开始慢慢深入了解.如果本文有什么不对的地方,请指出. 关于javasript,它是基于对象的,因此,它没有类的概念,所以,如果要实现继承,也就只能是利用javascript的原型机制prototype去实现了.(其实这里是错的,感谢 @记忆的森林 的提示,还可以用apply和call去实现) 因为javas

  • C++继承介绍

    然后是各个成员函数选项可以是virtual或non-virtual或pure virtual.本文仅仅作出一些关键点的验证. public继承,例如下: 复制代码 代码如下: class base {...} class derived:public base {...} 如果这样写,编译器会理解成类型为derived的对象同时也是类型为base的对象,但类型为base的对象不是类型为derived的对象.这点很重要.那么函数形参为base类型适用于derived,形参为derived不适用于b

  • 一篇文章超详细的介绍Java继承

    目录 前言 继承 继承的优点 重写和隐藏父类方法 重写父类中的方法 隐藏父类中的方法 方法重写和隐藏后的修饰符 子类访问父类私有成员 使用super关键字 使用super调用父类的无参数构造方法/有参数构造方法 附:继承的使用和认识 总结 前言 继承是面向对象语法的三大特征之一.继承可以降低代码编写的冗余度,提高编程的效率.通过继承,子类获得了父类的成员变量和方法.一个子类如何继承父类的字段和方法,如何修改从父类继承过来的子类的方法呢.今天我们开始学习有关Java继承的知识. 继承 继承就是子类

  • C++私有继承(一)

    目录 1.私有继承介绍 2.语法 3.类声明代码 文章转自微信公众号:Coder梁(ID:Coder_LT) 1.私有继承介绍 我们可以将一个类作为另外一个类的成员,这样可以描述has-a的关系,即包含关系. 例如我们要创建一个Student类,它当中要包含一个string类型的name,和valarray类型的scores.这里的valarray是C++中的一个模板类,它可以理解成一个泛型的数组,有些类似于vector和array,但提供的功能更多.比如拥有min, size, max, su

  • Java 的访问修饰符public,protected,private(封装、继承)

    目录 一.访问控制修饰符 二.封装(Encapsulation) 三.继承(Inheritance) (1) 引出继承 (2) 继承介绍 (3) 继承细节 一.访问控制修饰符 Access level modifiers determine whether other classes can use a particular field or invoke a particular method. 访问级别修饰符决定其他类是否可以使用特定成员变量或调用特定成员方法方法. Java 中有 4 个级

  • PHP类继承 extends使用介绍

    出来工作这么久了,项目经验倒是不少,但是当问及底层的东西时候,常常是一言不发了.现在项目设计底层的东西越来越少,可以说是真正用到的也就是那么一点,真正核心的东西都已经被框架封装好了.总感觉自己一直进步很慢,关于底层设计思想,常常也只可意会.随着时间的流逝,我们常常会感慨书到用时方恨少了,接下来一定要恶补设计思想了. 今天先来复习一下类继承. 类继承很重要,作为程序员也基本每天都会和他打交道,但是有些东西你真的都知道吗?下面是从官网上面看到的. 一个类可以在声明中用 extends,关键字继承另一

  • javascript的几种继承方法介绍

    1.原型链继承:构造函数.原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.确认原型和实例之间的关系用instanceof. 原型链继承缺点:字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数 function Parent(){ this.name='mike'; } function Child(){ this.age=12; } //儿子继承父亲(原型链) Child.prototype

  • 对python中类的继承与方法重写介绍

    1.单继承 父类也叫基类 子类也叫派生类 如下所示,继承的关系: 继承的书写格式: class 子类(父类): 方法 实例: class Animal: def eat(self): print("-----吃-------") def drink(self): print("-----喝--------") class Dog(Animal): def drak(self): print("汪汪叫") a=Animal() a.eat() 孙类

  • Python Django框架介绍之模板标签及模板的继承

    一.标签语法 由%}和 {% 来定义的,例如:{%tag%} {%endtag%},完整的标签有开始就有结束,如条件语句,有条件判断的开始,也对应有条件的结束. 二.常见标签 if条件判断 if/elif/else:可以使用and/or/in/not/==/!=/<=/>=,来进行判断.ifequal/ifnotequal for循环 for ... in ...:和python中的用法一样. forloop.counter:当前迭代的次数,下标从1开始.1,2,3.... forloop.c

随机推荐