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()
		{
			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"); 
		}
	
};

三.再谈构造和析构
当创建一个子类对象时
构造时,先调用父类的构造函数,再调用子类的构造函数
析构时,先调用子类的析构函数,再调用父类的构造函数

如果父类有多个构造函数时,可以显式的调用其中一个
如果没有显式的调用时,默认调用了默认构造函数。

什么是构造函数

愿景:任何事物的设计与制造,都带着未诞生前的愿景和期许,构造函数的美好期许是,在对象建立之初,对对象进行初始化,初始化的时候有函数的调用,需要完成一些功能。

程序性的东西是精准规范的事物,因此其命名很多时候是带着精准意义的,命名的意义大多数目的是为了一个简单的外号,伟大且带有意义的事物的发明就在于其携带的意义的多,同样是名字有的名字仅仅是一个可以从一定群体中辨别出你的一个代号,也可以命名的时候在名字里融入对生命的美好期许,正如很多父母对孩子的起名一样,带着对小生命的期待也带着父母作为一个人类本身对生命的感悟与祝福。

构造函数的命名,其本身命名是与定义的类是相同的。

既然是一个从属于整个种类的类别,我们每个个体又是生而不同的,每个个体都有着独一份的特点,有的美丽到令人窒息,有的深邃到令人沉迷,有的温柔到令人心疼。无数的不同,组成了一个如浩瀚繁星一样的无尽宇宙。我们并不是因为一点不同而不同,而是我们每个小世界的点点滴滴都有所不同。

构造函数从属于函数,但是却是没有返回值得函数。

一与无穷

很多事情,从诞生之初就携带着无数的遐想和猜测,,但聪明的人类,在自己的大脑里所能构造的有很多,无论是无穷还是1都可以使用,当面对浩瀚星海时候,人的内心充满的是震撼与浩大,当面对柴米油盐的时候,也可以实事求是做饭。

人因为数量的一与无穷而不同,孤星与星海是有所不同的,星海之间的无数羁绊本身,会比孤星多了很多美好遐想,天马流星、八月狮子、时空穿越、星海佳音。

构造函数可以有多个,可以带空参数。

提要和目录之间的合理性

世间的事情安排本身就是各司其职,各自在自己的小天地中潇洒自如,若有雄心的志向,人本身也可以自下而上。小小人类一生中琐事太多,因此,目录提要是为了提醒我们回归本位,还有一个就是量变引起质变的系统性。

所有的类都有构造函数:

如果没有定义构造函数,那么C++编译器会为它生成一个无参的、函数体为空的默认构造函数。

定义的时候会自动调用无参构造函数

当一个类被继承时,析构函数应该加上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{
};

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

猜你喜欢

转载自blog.csdn.net/u013590327/article/details/123189363