一.类的继承
class Shape{
};
class Circle : public Shape{
};
语法:class B : public A{}
B继承于A,A类是父类,B是派生类(子类)
当 B继承于A时,自动将父类中的所有public 成员继承,无法继承private的
新的修饰符:protected
(1)该成员不能被外部访问,如private
(2)该成员可以被子类继承,如public
在内存上描述父类和子类的关系:父类的内存在前面
父类的private成员变量也会出现在内存中,只是编译器限制了访问而已
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
class Shape{
public:
char name[16];
char size[16];
public:
void Show()
{
printf("%s ,%s \n",name,size);
}
protected:
int abc = 10;
};
class Circle : public Shape
{
//Circle自己的一些函数。
public:
void Play()
{
printf("abc = %d\n",abc);
}
};
int main()
{
Circle c;
strcpy(c.name,"xigua");
strcpy(c.size,"big");
c.Show();
c.Play();
return 0;
}
二.虚拟继承
1.函数的重写
class Parent{
public:
void test()
{
}
};
class Child:public Parent
{
public:
void test()
{
}
};
2.如果只是想在父类函数的基础上加一些代码
class Parent{
public:
void test()
{
printf("Parent.....\n");
}
};
class Child:public Parent
{
public:
void test()
{
Parent::test();
printf("Child.....\n");
}
};
3.父类指针可以指向子类的对象
class Parent{
public:
int a ;
};
class Child:public Parent
{
public:
int b;
};
int main()
{
Child c;
c.a = 10;
c.b = 20;
Parent* p = &c;
printf("%d \n",p->a);
return 0;
}
4.问题的引入:
Parent* p = new Child();
p->test();
指向的谁的test?
class Parent{
public:
void test()
{
printf("Parent.....\n");
}
};
class Child:public Parent
{
public:
void test()
{
printf("Child.....\n");
}
};
int main()
{
Child ch;
Parent* p = &ch;
p->test();
return 0;
}
当一个成员函数要被子类 重写 时,那么父类应该将其申明为virtual
如果父类函数被定义为 vitural 时将调用子类的
class Parent{
public:
virtual void test()
{
printf("Parent.....\n");
}
};
class Child:public Parent
{
public:
void test()
{
printf("Child.....\n");
}
};
三.再谈构造和析构
当创建一个子类对象时
构造时,先调用父类的构造函数,再调用子类的构造函数
析构时,先调用子类的析构函数,再调用父类的构造函数
如果父类有多个构造函数时,可以显式的调用其中一个
如果没有显式的调用时,默认调用了默认构造函数。
class Parent{
public:
Parent()
{
printf("创建\n");
a = b = 0;
}
Parent(int x,int y)
{
printf("创建 参数:%d, %d\n",x,y);
a = x;
b = y;
}
~Parent()
{
printf("销毁\n");
}
private:
int a,b;
};
class Child:public Parent
{
public:
Child():Parent(1,2)//显式的调用
{
printf("创建\n");
}
~Child()
{
printf("销毁\n");
}
};
int main()
{
{
Child ch;
printf("-----------\n");
}
return 0;
}
当一个类被继承时,析构函数应该加上virtual
考虑:
Parent * p = &ch;
delete p;
可能会导致程序崩溃
class Parent{
public:
Parent()
{
printf("Parent: 创建\n");
a = b = 0;
}
Parent(int x,int y)
{
printf("Parent: 创建 参数:%d, %d\n",x,y);
a = x;
b = y;
}
~Parent()
{
printf("Parent: 销毁\n");
}
private:
int a,b;
};
class Child:public Parent
{
public:
Child():Parent(1,2)//显式的调用
{
printf("Child: 创建\n");
}
~Child()
{
printf("Child: 销毁\n");
}
};
int main()
{
Parent* p= new Child();
delete p;
return 0;
}
**//改成virtual ~Parent**
四.多重继承
Father,Mother 表示两个类
class Child:public Father, public Mother{
};
多重继承的问题:当多个父类有相同变量时,会出错,所以运用的地方较少,在后面的纯虚函数会涉及。