C++继承

继承:继承是一种可以使代码复用的一种手段,允许在原有类的基础上产生新的类。

语法:在一个类后加上 : 继承方式 另一个类类名

继承方式:public,protected,private

class A
{

public:
	void fun()
	{
		cout << "fun" << endl;
	}
private:
	int a;
};
class B :public A
{
public:
	void print()
	{
		cout<<"print"<<endl;
	}
private:
	int b;
};
//B是派生类,A是基类
1.派生类的大小

派生类的大小:派生类的成员和基类的成员的总大小

class A
{
private:
	int a;
	int b;
	int c;
};
class B :public A
{
private:
	int b;//大小为4个int,16个字节
};
2.派生类继承基类,继承方式的权限是往里缩而不会往外扩的,public>protected>private。
class A
{
public:
	void show()
	{
		cout << "show" << endl;
	}
protected:
	void swap()
	{
		cout << "swap" << end
	}
private:
	void fun()
	{
		cout << "fun" << endl
	}
};
class B :protected A
{
public:
	void print()
	{
		cout<<"print"<<endl;
	}
};
int main()
{
	B b;
	b.show();//由于继承方式是protected,所以在基类A中原本public的show方法不能直接访问了,会出错
}
3.基类的私有成员在派生类是不允许直接被访问的,而共有成员和保护成员可以直接被访问,这也是私有和保护的区别
class A
{
public:
	void show()
	{
		cout << "show" << endl;
	}
protected:
	void swap()
	{
		cout << "swap" << end
	}
private:
	void fun()
	{
		cout << "fun" << endl
	}
};
class B :public A
{
public:
	void print()
	{
		show();
		swap();//在派生类可以直接访问基类的共有成员和保护成员
		fun();//不能直接访问基类的私有成员
	}
};
4.赋值语句规则
  1. 子类对象可以给父类对象赋值
  2. 子类对象的地址可以给父类对象的指针赋值
  3. 子类对象的引用可以给父类对象初始化
class A
{
public:
	int a;
};
class B:public A
{
public:
	int a;
};
int main()
{
	B b;
	A a;
	a = b;
	A*pa = &b;
	A&qa = b;
	return 0;
}

为什么可以赋值呢?来看一段代码

class A
{
public:
	A()
	{
		cout << "A::A" << endl;
	}
	~A()
	{
		cout << "A::~A" << endl;
	}
	int a;
};
class B :public A
{
public:
	B()
	{
		cout << "B::B" << endl;
	}
	~B()
	{
		cout << "B::~B" << endl;
	}
	int b;
};
int main()
{
	B b;
	return 0;
}

结果如下:
在这里插入图片描述
我们可以看到实例化了一个B对象,在调动B的构造函数时,会先调动A的构造函数,所以在b对象内部是有A的成员的.我们可以通过监视看到。
在这里插入图片描述
所以子类对象可以给父类赋值,是因为在子类里有父类成员。父类不能给子类赋值,因为父类里没有子类成员。这是赋值的本质。
当实例化一个子类对象,先调动基类的构造函数,再调动派生类的构造函数,析构时,先调动子类的析构函数,再调动基类的构造函数

5.同名函数

当派生类与有基类同名的函数时,会自动屏蔽掉基类的同名函数,只使用派生类的函数,如果一定要使用基类的函数: 派生类对象.基类::函数

class A
{
public:
	void fun()
	{
		cout << "A::fun()" << endl;
	}
	void fun(int a)
	{
		cout << "A::fun(a)" << endl;
	}
private:
	int a;
};
class B :public A
{
public:
	void fun()
	{
		cout << "B::fun()" << endl;
	}
private:
	int b;
};
int main()
{
	B b;
	b.fun();//子类的fun函数
	b.fun(0);//错误,子类没有这个函数
	b.A::fun(0);//父类的fun(int)函数
	return 0;
}
6.友元不能继承

我们知道,如果一个方法想要访问类的私有成员,可以将这个方法设为友元

class A
{
	friend void show(const A&a);
private:
	int m = 0;
};
class B :public A
{
private:
	int n = 0;
};
void show(const A&a)
{
	cout << "m = " << a.m << endl;
}
int main()
{
	A a;
	B b;
	show(a);
	return 0;
}

而我们使用继承,用父类的友元函数访问子类的私有成员来试试

class A
{
	friend void show(const A&a,const B&b);
private:
	int m = 0;
};
class B :public A
{
private:
	int n = 0;
};
void show(const A&a, const B&b)
{
	cout << "m = " << a.m << endl;
	cout << "n = " << b.n << endl; //不能通过编译,所以说明父类的友元并不能访问子类的私有成员

}
int main()
{
	A a;
	B b;
	show(a,b);
	return 0;
}

反过来也一样,子类的友元方法也不能访问父类的私有成员。
总结:友元在父子类中没有传递性,友元不能继承。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值