多年前学的C++,当时不努力。发现应聘起来人家就考这些。偏偏脑子里面记得的struct全是C语言里面的知识点。为了对的起大学里面的学费,咱又得重新看一下书。结果却发现C++中的结构体和C里面的很不一样,C++改进了很多。
面向对象
首先C++是美国贝尔实验室的博士在C的语言上弥补了C的一些缺陷,曾加了面向对象的特征,于1980年开发出来的一种过程性与对象性结合的程序设计语言。从这句课本上的定义我们来看:C++是一门面向对象的语言,因此我们才会在C++中接触到了类。因为C++的面向对象所以C++结构体也做到了面向对象,也就是说结构体和类在C++中是很相似的。我们来看下面的代码
struct realmath{ double real; double realcomplex() { return real; } };
这段代码在VC编译器中是完全没有问题(不信的可以试试)。也就是说和C语言相比较言,C++中的结构体能够添加函数方法。(C语言可以用函数指针我们就不讨论这函数指针算不算函数了)。那么好吧既然它能实现面向对象,那么我们来看看面向对象的特性:一封装,二继承,三多态。首先封装和继承我们就一起来考虑吧。
结构体和类的比较
我们用结构体和类来实现简单的数学复数功能,当然考虑到了继承我们先写一个实数,然后复数继承自实数,代码如下:
struct realmath{ double real; double realcomplex() { return real; } }; struct complex:realmath{ double imag; complex(double r,double i) { real=r; imag=i; } void init(double r,double i) { real=r;imag=i; } abscomplex() { double answer; answer = real*real-imag*imag; return sqrt(answer); } }; class Crealmath{ double real; double realcomplex() { return real; } }; class Ccomplex:Crealmath{ double imag; Ccomplex(double r,double i) { real=r; imag=i; } double imagcomplex() { return imag; } double abscomplex() { double answer; answer = real*real-imag*imag; return sqrt(answer); } };
这段代码能再编译器上通过吗?答案当然是否定的,我们通过编译系统的报错
F:\Program Files\Microsoft Visual Studio\MyProjects\Test\Test.cpp(100) : error C2248: 'real' : cannot access private member declared in class 'Crealmath' F:\Program Files\Microsoft Visual Studio\MyProjects\Test\Test.cpp(90) : see declaration of 'real'
也就是说我们在类的继承中是有问题的,为什么呢?当然基础知识扎实的一些就看出来,类中默认的成员变量的类型和继承是私有的,也就是说,我们在定义成员变量不声明,系统都会默认将它设为私有的。我们同时也发现结构体却没有报错。也就是说结构体的属性最起码不是默认为private的。就是说Class Craelmath的代码等效如下
class Crealmath{private: double real; double realcomplex() { return real; } }; class Ccomplex:private Crealmath{ double imag; Ccomplex(double r,double i) { real=r; imag=i; } double imagcomplex() { return imag; } double abscomplex() { double answer; answer = real*real-imag*imag; return sqrt(answer); } };
当然系统默认的结构体的继承方式是什么呢:public,为了证明这一点,我们来看成员和继承都是有访问属性的,也就是说,成员在派生类中的访问属性,是经过2次默认属性的叠加(上面代码中红色字体部分)。根据C++而言的话,能再派生类中访问的就是public和protected,但是这2个的叠加还是同样的,位于区分的就是能不能在类外调用了,所以我们在后面进行调用看看①。现在我们对继承是不是还有疑问呢?比如我是不是可以使用别的属性呢,或者说结构体中根本没有访问属性的限制呢?这个问题我们在最后再来阐述②。
多态
我们多态分为2种覆盖和重载了,我们可以在结构体中曾经相应的代码如下:
struct complex:realmath{ double imag; complex(double r,double i) { real=r; imag=i; } void init(double r,double i) { real=r;imag=i; } double realcomplex()//验证多态中的覆盖 { return real+1; } void Show(float a,float b)//验证重载 { cout<<"你调用的float参数的函数"<<endl; } void Show(int c)//验证重载 { cout<<"你调用的int参数的函数"<<endl; } double imagcomplex() { return imag; } double abscomplex() { double answer; answer = real*real-imag*imag; return sqrt(answer); } };
好了现在就是调用者写东西的时候,完整的代码如下
struct realmath{ double real; double realcomplex() { return real; } }; struct complex:realmath{ double imag; complex(double r,double i) { real=r; imag=i; } void init(double r,double i) { real=r;imag=i; } double realcomplex()//验证多态中的覆盖 { return real+1; } void Show(double a,double b)//验证重载 { cout<<"你调用的double参数的函数"<<endl; } void Show(int c)//验证重载 { cout<<"你调用的int参数的函数"<<endl; } double imagcomplex() { return imag; } double abscomplex() { double answer; answer = real*real-imag*imag; return sqrt(answer); } }; class Crealmath{ public: double real; double realcomplex() { return real; } }; class Ccomplex:public Crealmath{ public: double imag; Ccomplex(double r,double i) { real=r; imag=i; } double imagcomplex() { return imag; } double abscomplex() { double answer; answer = real*real-imag*imag; return sqrt(answer); } }; void main() { complex test1(2,1); cout<<test1.abscomplex()<<endl; cout<<test1.real<<endl;//验证默认的继承方式,如果保持说明结构体默认继承为Protected cout<<test1.realcomplex()<<endl;//输出结果是2则没有复盖,若为3则复写 test1.Show(2); test1.Show(1.1,1.1); Ccomplex test2(2.2,1.1); cout<<test2.abscomplex()<<endl;}
我们编译,OK没问题。我们在来分析结构,首先第一行货最后一行结果相同,说明结构体的方法没有问题,第2行有结果说明test1.real的属性为public,也就是说结构体的继承为公有继承这也就得出了前面①的结论,4,5行可以证明结构体支持多态。当然我现在可以来证明结构体是否支持属性声明。在结构体中曾经代码
struct realmath{ private: double real; double realcomplex() { return real; } };
我们现在来编译
F:\Program Files\Microsoft Visual Studio\MyProjects\Test\Test.cpp(77) : error C2248: 'real' : cannot access private member declared in class 'realmath' F:\Program Files\Microsoft Visual Studio\MyProjects\Test\Test.cpp(67) : see declaration of 'real'
也就是说结构体支持了属性限制。
结论
C++中的结构体可以近似看成是一个不安全的类。结构体的访问属性和继承属性都是默认为:public的。当然如果你要说它们的其他区别,哪就是什么说为内存分配形式一个用堆一个用栈了。这个笔者我也不是很懂。当然以上言论仅为个人观点,如果有误欢迎指正。