赞
踩
类描述看上去很像包含成员函数以及public和private可见性标签的结构声明,实际上,C++对结构进行了扩展,使之具有与类相同的特性。它们之间的唯一区别是:结构的默认访问类型是public,而类的默认访问类型为private。在C++中通常使用类来实现类描述,而把结构限制为只表示纯粹的数据对象(常被称为普通老数据POD(Plain Old Data)结构,)。
概念:class和struct的语法基本相同,从声明到使用,都很相似,但是struct的约束要比class多,理论上,struct能做到的class都能做到,但class能做到的stuct却不一定做的到。
类型:struct是值类型,class是引用类型,因此它们具有所有值类型和引用类型之间的差异。
效率:由于栈的执行效率要比堆的执行效率高,但是栈资源却很有限,不适合处理逻辑复杂的大对象,因此struct常用来处理作为基类型对待的小对象,而class来处理某个商业逻辑。
总结:
(1) 在表示诸如点、矩形等主要用来存储数据的轻量级对象时,首选struct。
(2) 在表示数据量大、逻辑复杂的大对象时,首选class。
(3) 在表现抽象和多级别的对象层次时,class是最佳选择
// 写法一 #include <stdio.h> typedef struct Actress { int height; // 身高 int weight; // 体重 int age; // 年龄(注意,这不是数据库,不必一定存储生日) void (*desc)(struct Actress*); } Actress; void profile(Actress* obj) { printf("height:%d weight:%d age:%d\n", obj->height, obj->weight, obj->age); } int main() { Actress a; a.height = 168; a.weight = 50; a.age = 20; a.desc = profile; a.desc(&a); return 0; }
想达到面向对象中数据和操作封装到一起的效果,只能给struct里面添加函数指针,然后给函数指针赋值。在C语言的项目中你很少会看到这种写法,主要原因就是函数指针是有空间成本的。一般会按照如下的方法写:
// 写法二 #include <stdio.h> typedef struct Actress { int height; // 身高 int weight; // 体重 int age; // 年龄(注意,这不是数据库,不必一定存储生日) } Actress; void desc(Actress* obj) { printf("height:%d weight:%d age:%d\n", obj->height, obj->weight, obj->age); } int main() { Actress a; a.height = 168; a.weight = 50; a.age = 20; desc(&a); return 0; }:
再看一个普通的C++类:
// 写法二 #include <stdio.h> class Actress { public: int height; // 身高 int weight; // 体重 int age; // 年龄(注意,这不是数据库,不必一定存储生日) void desc() { printf("height:%d weight:%d age:%d\n", height, weight, age); } }; int main() { Actress a; a.height = 168; a.weight = 50; a.age = 20; a.desc(); return 0; }
看着像写法一?其实相当于写法二。C++编译器实际会帮你生成一个类似C语言写法二的形式(这也算是C++ zero overhead指导方针的一个体现)。看到这里就明白了:C++中类和操作的封装只是对于程序员而言的。而编译器编译之后其实还是面向过程的代码。编译器帮你给成员函数增加一个额外的类指针参数,运行期间传入对象实际的指针。类的数据(成员变量)和操作(成员函数)其实还是分离的。
每个函数都有地址(指针),不管是全局函数还是成员函数在编译之后几乎类似。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。