10.继承和派生

  1. 类成员访问权限

成员访问权限:私有成员:只能被类自身的成员和友元访问

公有成员:可以被任何普通函数和任何类的成员函数或子类访问;

保护成员:可以被类自身的成员和友元、派生类的成员函数访问;

多重继承及二义性问题

(1)使用域运算符“::”    (2)使用同名覆盖原则(3)使用虚基类

  1. 虚基类

是指基类被virtual修饰,用来解决基类中由于同名成员的问题而产生的二义性问题。

虚拟继承声明:在派生类的声明过程中进行

class <派生类名>: virtual <派生方式><基类名>

虚基类成员在进一步派生过程中和派生类一起维护同一个内存复制

#include<iostream>
using namespace std;
class Base
{
  protected:
      int x;
  public:
      Base()
      {
        x=1;
      }
};
class Base1 : virtual public Base
{
   public:
    Base1()
    {
       cout<<"Constructing Base1,x="<<x<<endl;
    
     }
}
class Base2 : virtual public Base
{
   public:
     Base2()
     {
        cout<<"Constructing Base2,x="<<x<<endl;
     }
}
class Derived: public Base1,publice Base2
{
    public:
      Derived()
      {
         cout<<"Constructing Derived,x="<<x<<endl;
       }
}
int main()
{
    Derived obj;
    return 0;
}

虚基类的构造函数和初始化

基类构造函数》派生(虚基类的构造函数,非虚基类构造函数)

#include<isotream>
using namespace std;
class Base1
{
   int x1;
   public:
     Base1(int y1)
     {
        x1=y1;
        cout<<"constructing Base1, x1="<<x1<<endl;
      }
     ~Base1()
     {
         cout<<"destructing Base1"<<endl;
      }
};
class Base2
{
    int x2;
    pulice:
       Base2(int y2)
       {
          x2=y2;
          cout<<"constructing Base1, x2="<<x2<<endl;
       }
       ~Base2()
       {
           cout<<"destructing Base2"<<endl;
       }
};
class Derived : public Base2,public Base1
{
    private:
       Base1 ob1;
       Base2 ob2;
    public:
       Derived (int x,int y,int z,int v):Base1(x),Base2(y),ob1(z),ob2(v)
       {
          cout<<"constructing Derived"<<endl;
       }
};
int main()
{
    Derived ob(1,2,3,4);
    return 0;
}
使用虚基类注意事项:virtual与派生方式的关键字的书写位置无关紧要;一个基类在作为某些类的虚基类的同时也可作为另一些类的非虚基类;虚基类构造函数的参数必须由在新派生出来的类负责初始化,及时不是直接继承也应如此。

  1. 友元

:是为使类的私有成员和保护成员能够被其他类或其他成员函数访问。

友元函数:指友元是普通换书或类的成员函数

友元类:所有成员函数都成为友元函数

友元函数与普通成员函数不同,它不是当前类的成员函数,而是独立于当前类的外部函数;友元函数定义后可以访问该类的所有对象的所有成员,包括私有成员、保护成员和公有成员。

友元函数使用前必须要在类定义时声明;其定义既可以在类内部进行,也可以在类外部进行,但通常都定义在类的外部。

/*友元函数*/
#include<iostream>
using namespace std;
class Rectangle
{
   double length,width;
   public:
     Rectangle(double a=0,double b=0)//构造函数
     {
       length = a;
       width = b;
     }
     Rectangle(Rectangle &r);//重载构造函数
     friend double area(Rectangle &rectangle);
};
double area(Rectangle &rectangle)
{ 
    return (rectangle.length*rectangle.width);
}
int main()
{
   Rectangle ob(4,5);
   cout<<"The area is:"<<area(ob)<<endl;
   return 0;
}
使用友元函数注意的问题:(1)友元函数不是成员函数,因此,在类外定义友元函数时不用加”类名::“(2)友元函数不是类成员,因而不能直接引用对象成员名,必须通过作为入口参数传递,必须通过作为入口参数传递进来的对象名或对象指针来引用该对象的成员。(3)当一个函数需要访问多个类时,应该把这个函数同时定义为这些类的友元函数,这样才能访问这些类的数据。

友元成员:如果一个类的成员函数时另一个类的友元函数。这种机制可使两个类相互访问,从而共同完成某些任务。

/*友元成员*/
#include <iostream>
#include <string>
using namespace std;
class boy;
class girl;
{
   char *name;
   int age;
   public:
     girl(char *n,int a)
     {
       name = new char[strlen(n)+1];
       strcpy(name,n);
       age = a;
      }
     void prt(boy &b);
};
class boy
{
   char *name;
   int age;
   public:
     boy(char *n,int a)
     {
       name = new char[strlen(n)+1];
       strcpy(name,n);
       age = a;
     }
   friend void girl::prt(boy &b);
};
void girl::prt(boy &b)
{
   cout<<"girl\'s name:"<<name<<" age:"<<age<<"\n";
   cout<<"boy\'s name:"<<name<<" age:"<<age<<"\n";
}
int main()
{
  girl g1("Stacy",15);
  boy b1("Jim",16);
  g1.prt(b1);
  return 0;
} 
使用友元成员注意事项:(1)必须先定义成员函数所在的类(2)声明友元函数时,要加上成员函数所在类的类名和作用域运算符”::“(3)在主函数中一定要创建类的一个对象,只有这样才能通过对象名调用友元函数(4)如果在类定义前要使用到该类的成员,需要在使用前对该类进行声明。

友元类:

当一个类成为另一类的友元类时,这个类的所有成员函数都成为另一个类的友元函数。友元类中的所有成员函数都可以通过对象名直接访问另一个类中的所有成员,从而实现不同类之间的数据共享。

/*友元类*/
#include<iostream>
#include<string>
using namespace std;
class boy;
class girl
{ 
   char *name;
   int age;
   public:
     girl(char *n,int a)
     {
       name = new char[strlen(n)+1];
       strcpy(name,n);
       age = a;
     }
   void prt(boy &b);
};
class boy
{
   char *name;
   int age;
   friend class girl;//声明类girl为类boy的友元类
   public:
      boy(char *n,int a)
      {
        name = naw char[strlen(n)+1];
        strcpy(name,n);
        age = a;
      }
};
void girl::prt(boy &b)
{
   cout<<"girl \'s name:"<<name<<"  age:"<<age<<"\n";
   cout<<"girl \'s name:"<<name<<"  age"<<age<<"\n";
}
int main()
{
   girl g1("Stacy",15);
   boy b1("Jim",16);
   g1.prt(b1);
   return 0;
}



你可能感兴趣的:(10.继承和派生)