#include<iostream>
using namespace std;


class A
{
protected:
//int x, y;如果放在这里那么就相当于private 来访问了
public:
static int i;int x, y;


virtual void Happy()
{cout<<"I am from A!\n";
}


//virtual void Study () =0;//纯虚函数


void Set_value(int _x, int _y)
{
x = _x;
y = _y;
}


virtual double Area() 
{
return 0.0;
}


static void Add_i ()
{
i++;
cout<<i<<endl;
}


void Display () 
{
cout<<"x= "<<x<<endl
<<"y= "<<y<<endl;
}
};


int A::i=0;//只可以这样定义 类中的 static 成员变量!


class B:public A 
{
public:
void Happy() 
{
cout<<"I am from B!\n";
}
double Area()
{
return 0.5*x*y;
}
void Study()
{
cout<<"I am studying!\n";
}
};


void main()
{
A a;
//'void __thiscall A::Study(void)' : pure virtual function was not defined
//不能声明抽象类的对象,但可以声明指向抽象类的指针变量和引用变量。
B b;
a.Happy();
b.Happy();
cout<<"A.i= "<<A.i<<endl
<<"B.i= "<<B.i<<endl
<<"a.i= "<<a.i<<endl
<<"b.i= "<<b.i<<endl;
a.Set_value(4, 5);   //与下面的有区别!
cout<<a.Area()<<endl
<<b.Area()<<endl;


b.Set_value(8, 9);
cout<<a.Area()<<endl
<<b.Area()<<endl;


A* a1;
//B* b1;
a1 = &b;//可以用父类 的指针来 指向 派生类对象;//用派生类的指针指向父类 对象 就不怎么好了
//b1 = &a;  //error C2440: 'type cast' : cannot convert from 'class A *' to 'class B'


cout<<a1->Area()<<endl;//36


A& father1 = b;


//B& son1 = a;
//error C2440: 'initializing' : cannot convert from 'class A' to 'class B &'
//强制转换就可以!但是还是危险,所有就不提倡!
father1.Happy();//I am from B!


a1->Add_i();//1
cout<<"=============================\n";
B::Add_i();//2 static 函数成员只可以访问 static 数据成员!


//======================================
//现在是类 数据成员指针
A temp1;
int A::* p1 = &A::x;
temp1.*p1 = 20;//等价于a.x = 20;不要写成*p1 = 20;
p1 = &A::y;
temp1.*p1 = 30;//等价于a.y = 20;
temp1.Display();


// 现在是 类函数成员指针
void(A:: *F11)(int x, int y);//不要写成void (A::*F11(int x, int y));
F11 = A::Set_value;
(a.*F11)(1, 2);
a.Display();


}