C/C++类的继承

一.类的继承
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{
};

多重继承的问题:当多个父类有相同变量时,会出错,所以运用的地方较少,在后面的纯虚函数会涉及。

  • 41
    点赞
  • 136
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值