• c++ 小记


    1.构造函数不能声明为虚函数,析构函数可以声明为虚函数

    2 。 派生类对基类成员的访问规则

    派生类对基类成员的访问形式包括内部访问和对象访问两种方式。下面对3种继承方式下的访问规则分别进行介绍。

    1.私有继承

    通过私有继承方式,基类的公有成员和保护成员变为私有性质的,则派生类的其他成员可以直接访问基类的成员。但是派生类的对象不可以访问基类的成员,同时基类的私有成员不可以被派生类所访问。

    2.保护继承

    通过保护继承,基类的公有成员和保护成员变为保护性质的,则派生类的其他成员可以直接访问基类的成员。但是派生类的对象不可以访问基类的成员,同时基类的私有成员不可以被派生类所访问。这种方式与私有继承基本相同。

    3.         同名隐藏规则

    公有继承

    通过公有继承,基类的公有成员和保护成员仍为公有和保护成员。派生类的其他成员可以直接访问基类的公有成员和保护成员,但是派生类的外部只可以访问基类的公有成员。派生类的私有成员不能直接被访问,只可以通过公有成员和保护成员间接访问

    说明:继承方式的选择应该根据实际应用中的设计需要而定。一般来说选择公有继承方式的较多。

     

     

    3.

    当派生类与基类中有相同成员时:

    •若未强行指名,则通过派生类对象使用的是派生类中的同名成员。

    如要通过派生类对象访问基类中被覆盖的同名成员,应使用基类名限定

     

    4.

    void main()

    {  D1 d1;

      d1.nV=1;  //对象名.成员名标识, 访问D1类成员

      d1.fun();          

      d1.B1::nV=2;  //作用域分辨符标识, 访问基类B1成员

      d1.B1::fun(); 

      d1.B2::nV=3;  //作用域分辨符标识, 访问基类B2成员

      d1.B2::fun(); 

    }

    5.二义性解决方法

    •解决方法一:用类名来限定
    c1.A::f()    或    c1.B::f()
    •解决方法二:同名覆盖
    在C 中声明一个同名成员函数f(),再根据需要调用  A::f()    或    B::f()

     6.虚基类

    •虚基类的引入
    –用于有共同基类的场合
    •声明
    –以virtual修饰说明基类
    例:class B1:virtual public B
    •作用
    –主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题.
    –为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝
    •注意:

    在第一级继承时就要将共同基类设计为虚基类。

    #include <iostream>

    using namespace std;

    class B0 

    { public: 

           B0(char *s)  {  cout <<s<<endl; }

    };

    class B1: virtual public B0 

    {  public: 

      B1(char *s1,char *s2) : B0(s1)

           {  cout<<s2<<endl;}

    };

    class B2: virtual public B0 

    {  public: 

      B2(char *s1,char *s2) : B0(s1) {cout<<s2<<endl;}

    };

    class D1: public B1, public B2

    {

    public: 

      D1(char *s1,char *s2,char *s3,char *s4) : B0(s1), B1(s1,s2), B2(s3,s4)

          {cout<<s4<<endl;}

    };

    void main() 

    {

      D1 d("A","B","C","D"); 

    }

    结果:A B D D

    去掉B2 virtual  结果:AABDD

     7.  绑定类型

    •Binding(绑定)
    –程序自身彼此关联的过程,确定程序中的操作调用与执行该操作的代码间的关系。
    •Static binding(静态绑定)
    –The compiler knows which function to call based on the object that calls it.(绑定过程出现在编译阶段,用对象名或者类名来限定要调用的函数。)
    •Dynamic binding(动态绑定)
    –In dynamic binding, it is left until run-time to determine which function should be called.(绑定过程工作在程序运行时执行,在程序运行时才确定将要调用的函数。)
     
     

    #include<iostream>

    using namespace std;

    class Point

    { public:

      Point(double i, double j) {x=i; y=j;}

      double Area()  const{  return 0.0;}

      private:

      double x, y;

    };

    class Rectangle:public Point

    { public:

      Rectangle(double i, double j, double k, double l);

      double Area() const  {return  w*h;}

      private:

      double w,h;

    }

    Rectangle::Rectangle(double i, double j, double k, double l) :Point(i,j)

    {  w=k;  h=l; }

    void fun(Point &s)

    {  cout<<"Area="<<s.Area()<<endl;  }

    int main()

    {

      Rectangle rec(3.0, 5.2, 15.0, 25.0);

      fun(rec);

    }

    运行结果:

    Area=0

  • 相关阅读:
    在 git 上 push 之后的代码如何撤回
    Git 如何暂存代码
    使用 Maven 聚合⼯程创建微服务
    使用 K8spacket 和 Grafana 对 K8S 的 TCP 数据包流量可视化
    Ceph 存储的那点事儿 — Trim/Discard
    7 张图解 CrashLoopBackOff,如何发现问题并解决它?
    Kubernetes 和 容器的退出码完整指南
    刚刚 Kubernetes 1.25 正式发布,包括这些重大变化
    在 MacOS 上通过 Lima 使用 Docker
    Consul API Gateway 0.4 已正式发布,包括这些新功能
  • 原文地址:https://www.cnblogs.com/czsl/p/3170543.html
Copyright © 2020-2023  润新知