c++中关于类(class)和结构体(struct)的区别个人总结

多年前学的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的。当然如果你要说它们的其他区别,哪就是什么说为内存分配形式一个用堆一个用栈了。这个笔者我也不是很懂。当然以上言论仅为个人观点,如果有误欢迎指正。

猜你喜欢

转载自blog.csdn.net/www1157763637qqcom/article/details/16918099