1.2 关键词所带来的差异(A Keyword Distinction)

本文探讨了C++中的struct与class的区别及其在兼容C代码时的使用策略。通过实例说明了如何在C++中使用struct来保持与C的兼容性,以及在复杂情况下如何采用组合而非继承。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果不是为了努力维护与C之间的兼容性,C++远比现在更简单些。

如果C++并不需要支持C原有的struct,那么class的观念可以借由关键词class来支持。但是,从C迁徙到C++,除了效率,另外一个最长被程序员问道的问题就是:什么时候一个人应该再C++程序中以struct取代class?

关键词的困扰

答案之一是:当它让一个人感觉比较好的时候。

这个答案之处一个重要的特性:关键词struct本身并不一定象征其后随之声明的任何东西。我们可以使用struct取代class,但仍然声明public、protected、private等等存取字段与一个完全public的接口,以及virtual functions和单一继承、多重继承、虚拟继承......

如果这个语言只支持一个关键词,可以省掉许多混淆与迷惑。但是,如果C++要支持现存的C程序代码,它就不能不支持struct。引入class这个关键词,使人非常满意,因为这个语言所引入的不只是关键词,还有它支持的封装和继承的哲学。

策略性正确的struct(The Politiccally Conrrect Struct)

C程序员的巧设有时候却成为了C++程序员的陷阱。例如把一个元素的数组放在一个struct的尾端,于是每个struct objects可以拥有可变大小的数组:

struct mumble
{
	//stuff
	char pc[1];
};

//从档案或标准输入装置中取得一个字符串,
//然后为struct本身和该字符串配置足够的内存

struct mumble* pmum1 = (struct mumble*)
		malloc(sizeof(struct mumble) + strlen(string) + 1);
strcpy(&mumble.pc,string);

如果我们改用class来声明,而该class是:

  • 指定多个access sections,内含数据;
  • 从另一个class派生而来;
  • 定义一个或多个virtual functions

那么或许可以顺利转化,但也或许不行。

C++中凡处于同一个access section的数据,必定保证以其声明次序出现在内存布局中,然而被放置在多个access sections中的各笔数据,排列次序就不一定了。下面的声明,前述的C伎俩可以有效运行,或许不能,需视protect data members被放在private data members的前面或后面而定(放在前面才可以):

class stumble
{
public:
	//operations
protected:
	//protected stuff
private:
	char pc[1];
};

同样道理,base classes和derived classes的data member的布局也没有谁先谁后的强制规定,因而也就不能保证前述的C伎俩一定有效。Virtual functions的存在使前述伎俩的有效性成为一个问号。最好的忠告就是:不要那么做!

如果一个程序员迫切需要一个相当复杂的C++ class的某部分数据,使它拥有C声明的那样子,那么那一部分最好抽取出来成为一个独立的struct声明。将C和C++组合在一起的做法就是,从C struct中派生出C++的部分:

struct C_point{...};
class Point: public C_point{...};

于是C和C++的两种用法都可以获得支持:

extern void draw_line(Point,Point);
extern "C" void draw_rect(C_point,C_point);

draw_line(Point(0,0),Point(100,100));
draw_rect(Point(0,0),Point(100,100));

这种习惯用法现在不再被推荐,因为某些编译器(例如Microsoft C++)在支持virtual function的机制中对于class的继承布局做一些改变。推荐使用组合:

struct C_point{...};

class Point
{
public:
	operations C_point(){return _c_point;}
	// ...
private:
	C_point _c_point;
	// ...
};

C struct在C++中的一个合理用途,是当你要传递“一个复杂的class object 的全部或者部分”到某个C函数中去时,并保证拥有与C兼容的空间布局。然而这项保证只有在组合(composition)的情况下才存在。如果是“继承”而不是“组合”,编译器会决定是否应该有额外的data members被安插到base struct subobject之中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值