由于过去很长时间,属于跨行搞码,而且工作内容让我实际写代码的时间很少,所以加班之余找时间进行对c++进行总结学习,对跨行的同学进行一波鼓励,哈哈一定要多动手,当然要多看一些优秀的代码。
本章内容,参考c++编程思想
闲话不在多聊,开始正题------请点点关注-----请给个赞------请给条评论。
1.继承和静态成员函数
静态成员函数与非静态成员函数 共同点:
(1)它们均可以被继承到派生类中去。
(2)如果我们重定义了一个静态成员函数,基类的静态成员函数会被隐藏。
重点----静态函数不可以称为虚函数的。
2.私有继承和保护继承
在c++ 中类的继承是默认私有的。
class A:B; class A:private:B ;/// 这是私人有继承
class A:protected B;// 这是保护继承
class C:public B;//这是之前章节讲的,它们有什么区别。
如果是私有继承,派生类可以具备基类的所有数据和功能,但是对用户隐藏。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class A //基类
{
int i;
protected:
int c;
public:
void set(int ii){i==ii;cout<<"i ="<<i<<endl;}
void name(){cout<<"my name is A"<<endl;}
void see(){cout<<"you can't see me"<<endl;}
};
class B: A //私有继承
{
int j;
public :
void useA()
{
// i=0; error 不可访问 A 的私有成员变量
c=2;// 可以访问A 的
set(12);// 可以访问A 的public 变量
}
using A::name;
};
int main()
{
B b;
//b.see(); 用户不能访问A的成员变量和函数
b.name();///这个是特殊情况,因为在B 中的public 声明了A 的这个函数,可以用户可以访问的到
}
-------- 私有继承使用户无法访问基类的成员变量和函数,除非特别声明,我们在使用私有继承的时候,可以用组合的方式来来进行解决。
在实际项目中,我们希望某些基类隐藏起来,但是仍然希望派生类能够对其进行访问。
protected: 对于用户是隐藏的,对于派生类是可用的。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class A //基类
{
int i;
void private_(){}
protected:
int c;
void protected_(){}
public:
void set(int ii){i==ii;cout<<"i ="<<i<<endl;}
void public_(){cout<<"my name is A"<<endl;}
};
class B: public A //私有继承
{
int j;
public :
void useA()
{
//i=0; //error 不可访问 A 的私有成员变量
c=2;// 可以访问A 的 protected 变量
set(12);// 可以访问A 的public 变量
}
};
int main()
{
B b; //protecd 继承
//b.private_(); //用户不可以访问基类的私有成员变量,派生类也可以访问
//b.protected_();// 用户不可以访问基类的protected变量,派生类可以访问
b.public_();//用户和派生类都可以访问public。
}
可以看到procted 主要作用是为了,使某些成员可以被派生类访问,但不允许被用户访问,来保证程序的封装隐藏部分细节的特性。
3.继承---引起的向上类型转换。
class A::public B{};
所谓向上类型转换,就是A 的指针和引用可以转换成B 的指针和引用。
怎么理解,A 从B那学会了所有的功夫,所以当需要B的功夫的时候,A完全可以会。
所以我们会看到继承一个特别特别重要的属性-----
基类指针和引用 可以指向派生类对象。
这个特性可以帮我们做很多很多事情。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class A
{
public:
void hellow(){cout<<"hellow"<<endl;}
};
class B:public A{};
class C:public A{};
int main()
{
A* ptr_a[2];
ptr_a[0] = new B;
ptr_a[1] = new A;
for(int i =0;i<2;i++)
{
ptr_a[i]->hellow();
}
}
运行结果:
hellow
hellow
当我们有多个类派生于一个基类,给我们很多实现一些功能,很多操作空间。 下一部分,介绍虚函数。
4.向上类型转换和拷贝构造函数
编译器为派生类生成默认的拷贝构造函数,会自动调用基类的拷贝构造函数。然后是各个成员变量的拷贝构造函数,因此可以得到正确的操作。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class A //基类
{
int i;
public:
A(int ii){
i=ii;
cout<<"A(int)"<<i<<endl;
}
A(const A&a){
i=a.i;
cout<<"A(const A&):"<<i<<endl;
}
};
class B //成员,组合的方式
{
int i;
public:
B(int ii):i(ii){
cout<<"B(int):"<<i<<endl;
}
B(const B&b) {
cout<<"B:"<<i<<endl;
}
};
class C:public A
{
private:
/* data */
B b;
public:
C(int i=0):b(i),A::A(i){cout<<"C(int)"<<endl;}
~C(){};
};
int main()
{
C c_1(100);
C c_2=c_1;
}
结果
A(int)100
B(int):100
C(int)
A(const A&):100
B:0
A 是B的基类,首先调用A 的构造函数,其次调用成员变量的构造函数,最后调用C 的构造函数。
拷贝构造函数同理,因为上面C 没有创建拷贝构造函数。
如果要创建C 的拷贝构造函数,都要正确的调用基类的拷贝构造函数,否则会出错。正确形式。
C(const C&c):b(c.b),A(c){}
这里会有些奇怪,显示调用基类的拷贝构造函数,为什么是派生类的引用。
哈哈,这里就呈上所示,是引用 :向上类型转换了。
由于五一加班3天,昨天偷懒了。。。。昨天从下午四点睡到晚上8点,最近确实有些累,以后会加更,争取每日一更。