zoukankan      html  css  js  c++  java
  • 继承中的复制构造、赋值、析构、重载

    1.复制构造函数和赋值操作符

       在编写良好类的习惯文中知道了什么时候需要编写自己的复制构造函数、赋值操作符、析构函数后,当基类中需要这几个的时候,派生类当中就应该显式调用基类的复制构造函数和赋值操作符。如下:

    A(const A& s){a = s.a;std::cout<<"Has create A"<<std::endl;}
    
    ///B中的构造函数就应该这样(假设B继承于A):
    
    B(const B &v):A(v)
    {
           b = v.b;
    }
    

    值得一提的是 A(v)编译器会进行类类型转换;

    还有:不能写成这样:

    B(const B &v)
    {
               A(v);
               b = v.b;
    }
    
    

    这样编译器会提示 形参v重定义了;至于原因我大概测试了一下,应该是在构造B的时候,编译器会调用A的默认构造函数,然后再{}进行A的又一次构造,所以出现了重定义。

    这里要区分初始化列表跟构造函数{}里面操作意义是不一样的。

    赋值操作符也一样这样做:

    B& B::operator=(const B& b)
    {
        if(this!=&b)
        {
            A::operator=(b);
            ...................
         }
    }
    

    2.析构函数

    在继承层次当中,基类中就必须编写虚析构函数,原因很简单:

    静态指针类型跟动态指针类型不一样(要区分理解指针的静态类型跟动态类型):

    //B继承于A
    A *pa = new A;
    delete pa;
    pa = new B;//pa的动态类型发生改变
    delete pa;
    

    假如没有定义虚析构函数,编译器总是以静态对象类型来调用析构函数,然后再调用上一层次的析构函数,比如当静态类型是B类对象时候,编译器会先析构B类型对象b的,然后自动调用A的析构函数。但假如静态类型跟动态指针类型不一样,如上,且我们没有写虚析构函数,delete pa的时候总是只调用A的析构函数。现在明白为什么必须要为基类写虚析构函数了吧。

    3.继承中的重载

    继承关系中,重载函数只能发生于同一个层次中,也就是说假如基类跟派生类中出现函数名字一样,但函数原型不一样的时候,两者不构成函数关系,反而当派生类对象中是调用不了基类中的同名函数,也就是说屏蔽了基类对象中的那个同名函数。

    知道继承关系中的函数名字查找就可以了理解了,查找一个函数名字,先从静态对象类型的层次中查找,没有再往基类方向查找。

    点击这里给我发消息
  • 相关阅读:
    使用Task创建任务
    动态,静态库的发布和使用
    gcc编译
    knockout.js的学习笔记2
    网络爬虫基本原理(一)
    .Net项目分层与文件夹结构
    ASP.NET MVC的客户端验证:jQuery的验证
    ASP.NET MVC的客户端验证:jQuery验证在Model验证中的实现
    CMake 手册详解
    一个真实的应用程序 — 精通ASP.NET MVC 3
  • 原文地址:https://www.cnblogs.com/charm/p/1789729.html
Copyright © 2011-2022 走看看