• 学习第58天


    C++

    1. 继承的构造函数、

      1. 一个类只继承其直接基类(父类)的构造函数、默认、拷贝、移动构造函数是不能直接被继承的、

      2. using让某个名字在当前作用区域内可见、

        1. class a
          {
          public:
          	a(int a1,int a2,int a3){}
          };
          class b :public a
          {
          public:		
          using a::a//继承a的构造函数、编译到此时会把基类的每个构造函数都生成一个与之相对应的派生类构造函数、形参列表相同的派生类函数、函数体为空、
          };
          int main()
          {
          	b ab(10, 20, 30);
          }
          
      3. 如果基类a的构造函数有默认参数的话、编译器遇到using a::a的时候、就会在派生类b中构造多个构造函数、

      4. 其余的构造函数、则每个分别省略掉一个默认参数、

        1. class a
          {
          public:
          	a(int a1,int a2,int a3=100){}
          };
          class b :public a
          {
          public:
          	using a::a;//编译器会合成默认构造函数、
          };
          int main()
          {
          	b ab(10, 20);
          }
          
      5. 基类如果含有多个构造函数、一般情况下派生类会继承所有的这些构造函数、

      6. 特殊不会继承的情况、

        1. 派生类中定义的构造函数与基类构造函数相同的参数列表、基类中继承的构造函数会被派生类中定义覆盖掉、(只能继承未被覆盖的部分)派生类优先于基类
        2. 默认、拷贝、移动构造函数不会被继承、
    2. 多重继承、

      1. 多重继承、

        1. 从多个父类来产生出子类、

        2. 派生类会包含每个基类的子对象、

        3. class g
          {
          public:
          	g(int i) :m(i)
          	{}
          	virtual~g()
          	{}
          	void mo()
          	{
          		cout <<m<< endl;
          	}
          public:
          	int m;
          };
          class a :public g//继承g
          {
          public:
          	a(int  i) :g(i), ma(i)//每个子类的构造函数负责解决自己父类的初始化问题
          	{}
          	virtual ~a()
          	{}
          	void mo()
          	{
          		cout << ma << endl;
          	}
          public:
          	int ma;
          };
          class b //不继承g
          {
          public:
          	b(int i): mb(i)
          	{}
          	virtual ~b()
          	{}
          	void mo()
          	{
          		cout << mb << endl;
          	}
          public:
          	int mb;//定义
          };
          class c : public a, public b
          	//class  c:a,b//此为默认继承、看c决定、c是struct还是class class则是privaate(私有)继承、c是struct则是public(公用)继承
          {
          public:
          	c(int a1, int a2, int a3) :a(a1), b(a2), mc(a3)
          	{}
          	virtual~c()
          	{}
          	void mC()
          	{
          		cout << mc << endl;
          		a::mo();//调用a类中的mo函数
          		b::mo();//调用b类中的mo函数
          	}		
          public:
          	int mc;//定义成员
          };
          int main()
          {
          	c ct(20, 3, 4);
          	ct.mC();
          	ct.a :: mo();//增加作用域、明确系统该调用类a还是类b的成员函数
          }
          
      2. 静态成员变量、

        1. 静态成员是属于类而非是对象、

        2. 可以直接声明、但是使用必须要定义、因为定义时分配内存、

        3. class g
          {
          public:
          	g(int i) :m(i)
          	{
          
          	}
          	virtual~g()
          	{
          	}
          	void mo()
          	{
          		cout <<m<< endl;
          	}
          public:
          	int m;
          public:
          	static int  mic;//声明静态成员、
          };
          int g::mic=3;//定义静态成员并赋初值、可以不赋初值、
          class a :public g//继承g
          {
          public:
          	a(int  i) :g(i), ma(i)//每个子类的构造函数负责解决自己父类的初始化问题
          	{
          
          	}
          	virtual ~a()
          	{
          	}
          	void mo()
          	{
          		cout << ma << endl;
          	}
          public:
          	int ma;
          };
          class b //不继承g
          {
          public:
          	b(int i): mb(i)
          	{
          	}
          	virtual ~b()
          	{
          	}
          	void mo()
          	{
          		cout << mb << endl;
          	}
          public:
          	int mb;//定义
          };
          class c : public a, public b
          	//class  c:a,b//此为默认继承、看c决定、c是struct还是class class则是privaate(私有)继承、c是struct则是public(公用)继承
          {
          public:
          	c(int a1, int a2, int a3) :a(a1), b(a2), mc(a3)
          	{
          	}
          	virtual~c()
          	{
          	}
          	void mC()
          	{
          		cout << mc << endl;
          		a::mo();//调用a类中的mo函数
          		b::mo();//调用b类中的mo函数
          	}
          		
          public:
          	int mc;//定义成员
          };
          int main()
          {
          	c ct(20, 3, 4);
          	ct.mC();
          	ct.a :: mo();//增加作用域、明确系统该调用类a还是类b的成员函数
          	g::mic = 30;//直接用类名来引用静态变量、
          	//b::mic = 70;//不可以因为b没有继承g
          	c::mic = 60;//可以是因为c继承了a
          	a::mic = 50;//可以是因为a继承了g
          	ct.mic = 20;//对象也可以引用、
          }
          
      3. 派生类构造函数与析构函数、

        1. 构造一个派生类对象将同时构造并初始化私有的基类对象、

        2. 派生类的构造函数初始化列表只初始化它的直接基类、每个类的构造函数都负责初始化它的直接基类、

        3. 派生类构造函数初始化列表将实参分别传递到每个直接基类、基类和派生类列表出现的顺序保持一致、最先构造最后释放、

        4. class g
          {
          public:
          	g(int i) :m(i)
          	{
          		cout << "执行g构造函数" << endl;
          	}
          	virtual~g()
          	{
          		cout << "执行g析构函数" << endl;
          	}
          	void mo()
          	{
          		cout <<m<< endl;
          	}
          public:
          	int m;
          };
          class a :public g//继承g
          {
          public:
          	a(int  i) :g(i), ma(i)//每个子类的构造函数负责解决自己父类的初始化问题
          	{
          		cout << "执行a构造函数" << endl;
          	}
          	virtual ~a()
          	{
          		cout << "执行a析构函数" << endl;
          	}
          	void mo()
          	{
          		cout << ma << endl;
          	}
          public:
          	int ma;
          };
          class b //不继承g
          {
          public:
          	b(int i): mb(i)
          	{
          		cout << "执行b构造函数" << endl;
          	}
          	virtual ~b()
          	{
          		cout << "执行b析构函数" << endl;
          	}
          	void mo()
          	{
          		cout << mb << endl;
          	}
          public:
          	int mb;//定义
          };
          class c : public a, public b//派生列表
          {
          public:
          	c(int a1, int a2, int a3) :a(a1), b(a2), mc(a3)
          	{
          		cout << "执行c构造函数" << endl;
          	}
          	virtual~c()
          	{
          		cout << "执行c析构函数" << endl;
          	}
          	void mC()
          	{
          		cout << mc << endl;
          		a::mo();//调用a类中的mo函数
          		b::mo();//调用b类中的mo函数
          	}	
          public:
          	int mc;//定义成员
          };
          int main()
          {
          	c ct(20, 3, 4);
          
        5. 显示初始化基类和隐式初始化基类(不带参数的构造函数、默认构造函数)、

      4. 从多个父类继承构造函数、

        1. 一个类从他的基类中继承相同的构造函数、该类就必须未该走构造函数定义属于自己的函数、

        2. 子类要定义同参数的自己构造函数、

        3. class a {
          public:
          	a(int t) {};
          
          };
          class b{
          public:
          	b(int t) {};
          
          };
          class c:public a,public b
          
          {
          public:
          	using a::a;//继承a
          	using b::b;//继承b
          	c(int t) :a(t), b(t) {};
          
    3. 虚基类、虚继承

      1. 一般来说、派生列表中同一个基类只能出现一次、

      2. 派生类可以通过它的俩个直接基类分别继承 同一个间接基类、

      3. 直接继承某一个基类、然后通过另一个基类间接继承该基类、

      4. 同一基类被继承两次会产生名字冲突(两个名字)、虚继承为此而生、

      5. 虚继承无论出现多少次、派生类只包含一个共享的虚基类子内容、(就没有名字冲突)、

      6. 虚继承仅对子类所派生的子类有效、对基类派生的子类无效、

      7. virtual——虚继承、

      8. 虚基类由子类初始化父类的父类、最后的子类初始化最初的父类、如果d继承了c则由d初始化g、

      9. 最低类的派生初始化最高的基类、在虚继承中最先初始化虚继承的类然后在按照派生列表来初始化其它的类、

      10. 虚基类的销毁和构造顺序相反、多个虚基类则追溯时初始化、

      11. class g
        {
        public:
        	g(int i) :m(i)
        	{
        		cout << "执行g构造函数" << endl;
        	}
        	virtual~g()
        	{
        		cout << "执行g析构函数" << endl;
        	}
        	void mo()
        	{
        		cout <<m<< endl;
        	}
        public:
        	int m;
        
        };
        class a : virtual public g//虚基类
        {
        public:
        	a(int  i) :g(i), ma(i)
        	{
        		cout << "执行a构造函数" << endl;
        	}
        	virtual ~a()
        	{
        		cout << "执行a析构函数" << endl;
        	}
        	void mo()
        	{
        		cout << ma << endl;
        	}
        public:
        	int ma;
        };
        class j : virtual public g//虚基类
        {
        public:
        	j(int  i) :g(i), ma1(i)
        	{
        		cout << "执行a1构造函数" << endl;
        	}
        	virtual ~j()
        	{
        		cout << "执行a1析构函数" << endl;
        	}
        	void mo()
        	{
        		cout << ma1 << endl;
        	}
        public:
        	int ma1;
        };
        class b //不继承g
        {
        public:
        	b(int i): mb(i)
        	{
        		cout << "执行b构造函数" << endl;
        	}
        	virtual ~b()
        	{
        		cout << "执行b析构函数" << endl;
        	}
        	void mo()
        	{
        		cout << mb << endl;
        	}
        public:
        	int mb;//定义
        };
        class c : public a, public j, public b//class  c:a,b//此为默认继承、看c决定、c是struct还是class class则是privaate(私有)继承、c是struct则是public(公用)继承
        {
        public:
        	c(int a1, int a2, int a3) :a(a1),j(a1),g(a1), b(a2), mc(a3)//初始化g
        	{
        		cout << "执行c构造函数" << endl;
        	}
        	virtual~c()
        	{
        		cout << "执行c析构函数" << endl;
        	}
        	void mC()
        	{
        		cout << mc << endl;
        		a::mo();//调用a类中的mo函数
        		b::mo();//调用b类中的mo函数
        	}
        		
        public:
        	int mc;//定义成员
        };
        int main()
        {
        //g* p = new c(23, 34, 33);
        	c ct(20, 3, 4);//g会被继承两次、会产生名字冲突、
        	//ct.mo = 23;//虚继承为了解决此冲突、虚继承进队c有效对a和j均无效
        }
        
    4. 总结

      1. 慎用虚基类、容易出现二义性、
  • 相关阅读:
    获取SpringMVC的映射路径
    Spring任务调度之Quartz集成
    Spring任务调度之SpringTask基于XML和基于注解的使用示例
    Redis分布式集群搭建
    京东软开实习岗
    C语言编程练习(一)
    servlet温习
    tomcat启动超过时间
    JDK版本更换,Eclipse中所有的项目报错
    Myeclipse2017C版本破解
  • 原文地址:https://www.cnblogs.com/chengyaohui/p/13854200.html
Copyright © 2020-2023  润新知