Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
C++³ÌÐòÔ±Protocol Buffers»ù´¡Ö¸ÄÏ
 
 À´Ô´£ºsegmentfault   ·¢²¼ÓÚ£º2016-11-16
  1993  次浏览      27
 

ÕâÆª½Ì³ÌÌṩÁËÒ»¸öÃæÏò C++ ³ÌÐòÔ±¹ØÓÚ protocol buffers µÄ»ù´¡½éÉÜ¡£Í¨¹ý´´½¨Ò»¸ö¼òµ¥µÄʾÀýÓ¦ÓóÌÐò£¬Ëü½«ÏòÎÒÃÇչʾ£º

ÔÚ .proto ÎļþÖж¨ÒåÏûÏ¢¸ñʽ

ʹÓà protocol buffer ±àÒëÆ÷

ʹÓà C++ protocol buffer API ¶ÁдÏûÏ¢

Õâ²»ÊÇÒ»¸ö¹ØÓÚÔÚ C++ ÖÐʹÓà protocol buffers µÄÈ«ÃæÖ¸ÄÏ¡£Òª»ñÈ¡¸üÏêϸµÄÐÅÏ¢£¬Çë²Î¿¼ Protocol Buffer Language Guide ºÍ Encoding Reference¡£

ΪʲôʹÓà Protocol Buffers

ÎÒÃǽÓÏÂÀ´ÒªÊ¹ÓõÄÀý×ÓÊÇÒ»¸ö·Ç³£¼òµ¥µÄ"µØÖ·²¾"Ó¦ÓóÌÐò£¬ËüÄÜ´ÓÎļþÖжÁÈ¡ÁªÏµÈËÏêϸÐÅÏ¢¡£µØÖ·²¾ÖеÄÿһ¸öÈ˶¼ÓÐÒ»¸öÃû×Ö¡¢ID¡¢ÓʼþµØÖ·ºÍÁªÏµµç»°¡£

ÈçºÎÐòÁл¯ºÍ»ñÈ¡½á¹¹»¯µÄÊý¾Ý?ÕâÀïÓм¸ÖÖ½â¾ö·½°¸£º

ÒÔ¶þ½øÖÆÐÎʽ·¢ËÍ/½ÓÊÕÔ­ÉúµÄÄÚ´æÊý¾Ý½á¹¹¡£Í¨³££¬ÕâÊÇÒ»ÖÖ´àÈõµÄ·½·¨£¬ÒòΪ½ÓÊÕ/¶ÁÈ¡´úÂë±ØÐë»ùÓÚÍêÈ«ÏàͬµÄÄÚ´æ²¼¾Ö¡¢´óС¶ËµÈ»·¾³½øÐбàÒ롣ͬʱ£¬µ±ÎļþÔö¼Óʱ£¬Ô­Ê¼¸ñʽÊý¾Ý»áËæ×ÅÓë¸Ã¸ñʽÏà¹ØµÄÈí¼þ¶øÑ¸ËÙÀ©É¢£¬Õ⽫µ¼ÖºÜÄÑÀ©Õ¹Îļþ¸ñʽ¡£

Äã¿ÉÒÔ´´ÔìÒ»ÖÖ ad-hoc ·½·¨£¬½«Êý¾ÝÏî±àÂëΪһ¸ö×Ö·û´®¡ª¡ª±ÈÈ罫 4 ¸öÕûÊý±àÂëΪ 12:3:-23:67¡£ËäÈ»ËüÐèÒª±àдһ´ÎÐԵıàÂëºÍ½âÂë´úÂëÇÒ½âÂëÐèÒªºÄ·ÑÒ»µãÔËÐÐʱ³É±¾£¬µ«ÕâÊÇÒ»ÖÖ¼òµ¥Áé»îµÄ·½·¨¡£Õâ×îÊʺϱàÂë·Ç³£¼òµ¥µÄÊý¾Ý¡£

ÐòÁл¯Êý¾ÝΪ XML¡£ÕâÖÖ·½·¨ÊǷdz£ÎüÒýÈ˵ģ¬ÒòΪ XML ÊÇÒ»ÖÖÊʺÏÈËÔĶÁµÄ¸ñʽ£¬²¢ÇÒÓÐΪÐí¶àÓïÑÔ¿ª·¢µÄ¿â¡£Èç¹ûÄãÏëÓëÆäËû³ÌÐòºÍÏîÄ¿¹²ÏíÊý¾Ý£¬Õâ¿ÉÄÜÊÇÒ»ÖÖ²»´íµÄÑ¡Ôñ¡£È»¶ø£¬ÖÚËùÖÜÖª£¬XML ÊǿռäÃܼ¯Ð͵ģ¬ÇÒÔÚ±àÂëºÍ½âÂëʱ£¬Ëü¶Ô³ÌÐò»áÔì³É¾Þ´óµÄÐÔÄÜËðʧ¡£Í¬Ê±£¬Ê¹Óà XML DOM Ê÷±»ÈÏΪ±È²Ù×÷Ò»¸öÀàµÄ¼òµ¥×ֶθü¼Ó¸´ÔÓ¡£

Protocol buffers ÊÇÕë¶ÔÕâ¸öÎÊÌâµÄÒ»ÖÖÁé»î¡¢¸ßЧ¡¢×Ô¶¯»¯µÄ½â¾ö·½°¸¡£Ê¹Óà Protocol buffers£¬ÄãÐèҪдһ¸ö .proto ˵Ã÷£¬ÓÃÓÚÃèÊöÄãËùÏ£Íû´æ´¢µÄÊý¾Ý½á¹¹¡£ÀûÓà .proto Îļþ£¬protocol buffer ±àÒëÆ÷¿ÉÒÔ´´½¨Ò»¸öÀ࣬ÓÃÓÚʵÏÖ¶Ô¸ßЧµÄ¶þ½øÖƸñʽµÄ protocol buffer Êý¾ÝµÄ×Ô¶¯»¯±àÂëºÍ½âÂë¡£²úÉúµÄÀàÌṩÁ˹¹Ôì protocol buffer µÄ×Ö¶ÎµÄ getters ºÍ setters£¬²¢ÇÒ×÷Ϊһ¸öµ¥ÔªÀ´´¦Àí¶Áд protocol buffer µÄϸ½Ú¡£ÖØÒªµÄÊÇ£¬protocol buffer ¸ñʽ֧³Ö¸ñʽµÄÀ©Õ¹£¬´úÂëÈÔÈ»¿ÉÒÔ¶ÁÈ¡ÒԾɸñʽ±àÂëµÄÊý¾Ý¡£

ÔÚÄÄ¿ÉÒÔÕÒµ½Ê¾Àý´úÂë

ʾÀý´úÂë±»°üº¬ÓÚÔ´´úÂë°ü£¬Î»ÓÚ¡°examples¡±Îļþ¼Ð¡£¿ÉÔÚÕâÀïÏÂÔØ´úÂë¡£

¶¨ÒåÄãµÄЭÒé¸ñʽ

ΪÁË´´½¨×Ô¼ºµÄµØÖ·²¾Ó¦ÓóÌÐò£¬ÄãÐèÒª´Ó .proto ¿ªÊ¼¡£.proto ÎļþÖе͍ÒåºÜ¼òµ¥£ºÎªÄãËùÐèÒªÐòÁл¯µÄÿ¸öÊý¾Ý½á¹¹Ìí¼ÓÒ»¸öÏûÏ¢(message)£¬È»ºóΪÏûÏ¢ÖеÄÿһ¸ö×Ö¶ÎÖ¸¶¨Ò»¸öÃû×ÖºÍÀàÐÍ¡£ÕâÀïÊǶ¨ÒåÄãÏûÏ¢µÄ .proto Îļþ addressbook.proto¡£

package tutorial; 
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
}
message AddressBook {
repeated Person person = 1;
}

ÈçÄãËù¼û£¬ÆäÓï·¨ÀàËÆÓÚ C++ »ò Java¡£ÎÒÃÇ¿ªÊ¼¿´¿´ÎļþµÄÿһ²¿·ÖÄÚÈÝ×öÁËʲô¡£

.proto ÎļþÒÔÒ»¸ö package ÉùÃ÷¿ªÊ¼£¬Õâ¿ÉÒÔ±ÜÃⲻͬÏîÄ¿µÄÃüÃû³åÍ»¡£ÔÚ C++£¬ÄãÉú³ÉµÄÀà»á±»ÖÃÓÚÓë package Ãû×ÖÒ»ÑùµÄÃüÃû¿Õ¼ä¡£

ÏÂÒ»²½£¬ÄãÐèÒª¶¨ÒåÏûÏ¢(message)¡£ÏûÏ¢Ö»ÊÇÒ»¸ö°üº¬Ò»ÏµÁÐÀàÐÍ×ֶεļ¯ºÏ¡£´ó¶à±ê×¼µÄ¼òµ¥Êý¾ÝÀàÐÍÊÇ¿ÉÒÔ×÷Ϊ×Ö¶ÎÀàÐ͵쬰üÀ¨ bool¡¢int32¡¢float¡¢double ºÍ string¡£ÄãÒ²¿ÉÒÔͨ¹ýʹÓÃÆäËûÏûÏ¢ÀàÐÍ×÷Ϊ×Ö¶ÎÀàÐÍ£¬½«¸ü¶àµÄÊý¾Ý½á¹¹Ìí¼Óµ½ÄãµÄÏûÏ¢ÖСª¡ªÔÚÒÔÉϵÄʾÀý£¬Person ÏûÏ¢°üº¬ÁË PhoneNumber ÏûÏ¢£¬Í¬Ê± AddressBook ÏûÏ¢°üº¬ Person ÏûÏ¢¡£ÄãÉõÖÁ¿ÉÒÔ¶¨ÒåǶÌ×ÔÚÆäËûÏûÏ¢ÄÚµÄÏûÏ¢ÀàÐÍ¡ª¡ªÈçÄãËù¼û£¬PhoneNumber ÀàÐͶ¨ÒåÓÚ Person ÄÚ²¿¡£Èç¹ûÄãÏëÒªÆäÖÐijһ¸ö×ֶεÄÖµÊÇÔ¤¶¨ÒåÖµÁбíÖеÄij¸öÖµ£¬ÄãÒ²¿ÉÒÔ¶¨Òå enum ÀàÐÍ¡ª¡ªÕâ¶ùÄã¿ÉÒÔÖ¸¶¨Ò»¸öµç»°ºÅÂëÊÇ MOBILE¡¢HOME »ò WORK ÖеÄijһ¸ö¡£

ÿһ¸öÔªËØÉ쵀 = 1¡¢= 2 ±ê¼ÇÈ·¶¨ÁËÓÃÓÚ¶þ½øÖƱàÂëµÄΨһ¡°±êÇ©¡±(tag)¡£±êÇ©Êý×Ö 1-15 µÄ±àÂë±È¸ü´óµÄÊý×ÖÉÙÐèÒªÒ»¸ö×Ö½Ú£¬Òò´Ë×÷ΪһÖÖÓÅ»¯£¬Äã¿ÉÒÔ½«ÕâЩ±êÇ©ÓÃÓÚ¾­³£Ê¹ÓõÄÔªËØ»ò repeated ÔªËØ£¬Ê£Ï 16 ÒÔ¼°¸ü¸ßµÄ±êÇ©ÓÃÓڷǾ­³£Ê¹ÓõÄÔªËØ»ò optional ÔªËØ¡£Ã¿Ò»¸ö repeated ×ֶεÄÔªËØÐèÒªÖØÐ±àÂë±êÇ©Êý×Ö£¬Òò´Ë repeated ×Ö¶ÎÊʺÏÓÚʹÓÃÕâÖÖÓÅ»¯ÊֶΡ£

ÿһ¸ö×ֶαØÐëʹÓÃÏÂÃæµÄÐÞÊηû¼ÓÒÔ±ê×¢£º

required£º±ØÐëÌṩ¸Ã×ֶεÄÖµ£¬·ñÔòÏûÏ¢»á±»ÈÏΪÊÇ ¡°Î´³õʼ»¯µÄ¡±(uninitialized)¡£Èç¹û libprotobuf ÒÔµ÷ÊÔģʽ±àÒ룬ÐòÁл¯Î´³õʼ»¯µÄÏûÏ¢½«ÒýÆðÒ»¸ö¶ÏÑÔʧ°Ü¡£ÒÔÓÅ»¯ÐÎʽ¹¹½¨£¬½«»áÌø¹ý¼ì²é£¬²¢ÇÒÎÞÂÛÈçºÎ¶¼»áдÈë¸ÃÏûÏ¢¡£È»¶ø£¬½âÎöδ³õʼ»¯µÄÏûÏ¢×ÜÊÇ»áʧ°Ü(ͨ¹ý parse ·½·¨·µ»Ø false)¡£³ý´ËÖ®Í⣬һ¸ö required ×ֶεıíÏÖÓë optional ×Ö¶ÎÍêȫһÑù¡£

optional£º×ֶοÉÄܻᱻÉèÖã¬Ò²¿ÉÄܲ»»á¡£Èç¹ûÒ»¸ö optional ×Ö¶Îû±»ÉèÖã¬Ëü½«Ê¹ÓÃĬÈÏÖµ¡£¶ÔÓÚ¼òµ¥ÀàÐÍ£¬Äã¿ÉÒÔÖ¸¶¨Äã×Ô¼ºµÄĬÈÏÖµ£¬ÕýÈçÀý×ÓÖÐÎÒÃǶԵ绰ºÅÂëµÄ type Ò»Ñù£¬·ñÔòʹÓÃϵͳĬÈÏÖµ£ºÊý×ÖÀàÐÍΪ 0¡¢×Ö·û´®Îª¿Õ×Ö·û´®¡¢²¼¶ûֵΪ false¡£¶ÔÓÚǶÌ×ÏûÏ¢£¬Ä¬ÈÏÖµ×ÜΪÏûÏ¢µÄ¡°Ä¬ÈÏʵÀý¡±»ò¡°Ô­ÐÍ¡±£¬ËüµÄËùÓÐ×ֶζ¼Ã»±»ÉèÖᣵ÷Óà accessor À´»ñȡһ¸öûÓÐÏÔʽÉèÖÃµÄ optional(»ò required) ×ֶεÄÖµ×ÜÊÇ·µ»Ø×ֶεÄĬÈÏÖµ¡£

repeated£º×ֶοÉÒÔÖØ¸´ÈÎÒâ´ÎÊý(°üÀ¨ 0 ´Î)¡£repeated ÖµµÄ˳Ðò»á±»±£´æÓÚ protocol buffer¡£¿ÉÒÔ½« repeated ×Ö¶ÎÏëÏóΪ¶¯Ì¬´óСµÄÊý×é¡£

Äã¿ÉÒÔ²éÕÒ¹ØÓÚ±àд .proto ÎļþµÄÍêÕûÖ¸µ¼¡ª¡ª°üÀ¨ËùÓпÉÄܵÄ×Ö¶ÎÀàÐÍ¡ª¡ªÔÚ Protocol Buffer Language Guide ÀïÃæ¡£²»ÒªÔÚÕâÀïÃæ²éÕÒÓëÀà¼Ì³ÐÏàËÆµÄÌØÐÔ£¬ÒòΪ protocol buffers ²»»á×öÕâЩ¡£

required ÊÇÓÀ¾ÃÐÔµÄ

ÔÚ°ÑÒ»¸ö×ֶαêʶΪ required µÄʱºò£¬ÄãÓ¦¸ÃÌØ±ðСÐÄ¡£Èç¹ûÔÚijЩÇé¿öÏÂÄã²»ÏëдÈë»òÕß·¢ËÍÒ»¸ö required µÄ×ֶΣ¬ÄÇô½«¸Ã×ֶθü¸ÄΪ optional ¿ÉÄÜ»áÓöµ½ÎÊÌ⡪¡ª¾É°æ±¾µÄ¶ÁÕß(LCTT Òë×¢£º¼´¶ÁÈ¡¡¢½âÎö¾É°æ±¾ Protocol Buffer ÏûÏ¢µÄÒ»·½)»áÈÏΪ²»º¬¸Ã×ֶεÄÏûÏ¢ÊDz»ÍêÕûµÄ£¬´Ó¶øÓпÉÄÜ»á¾Ü¾ø½âÎö¡£ÔÚÕâÖÖÇé¿öÏ£¬ÄãÓ¦¸Ã¿¼ÂDZàÐ´ÌØ±ðÕë¶ÔÓÚÓ¦ÓóÌÐòµÄ¡¢×Ô¶¨ÒåµÄÏûϢУÑ麯Êý¡£Google µÄһЩ¹¤³ÌʦµÃ³öÁËÒ»¸ö½áÂÛ£ºÊ¹Óà required ±×¶àÓÚÀû;ËûÃǸüÔ¸ÒâʹÓà optional ºÍ repeated ¶ø²»ÊÇ required¡£µ±È»£¬Õâ¸ö¹Ûµã²¢²»¾ßÓÐÆÕ±éÐÔ¡£

±àÒëÄãµÄ Protocol Buffers

¼ÈÈ»ÄãÓÐÁËÒ»¸ö .proto£¬ÄÇÄãÐèÒª×öµÄÏÂÒ»¼þʾÍÊÇÉú³ÉÒ»¸ö½«ÓÃÓÚ¶Áд AddressBook ÏûÏ¢µÄÀà(´Ó¶ø°üÀ¨ Person ºÍ PhoneNumber)¡£ÎªÁË×öµ½ÕâÑù£¬ÄãÐèÒªÔÚÄãµÄ .proto ÉÏÔËÐÐ protocol buffer ±àÒëÆ÷ protoc£º

1.Èç¹ûÄãûÓа²×°±àÒëÆ÷£¬ÇëÏÂÔØÕâ¸ö°ü£¬²¢°´ÕÕ README ÖеÄÖ¸Áî½øÐа²×°¡£

2.ÏÖÔÚÔËÐбàÒëÆ÷£¬Ö¸¶¨Ô´Ä¿Â¼(ÄãµÄÓ¦ÓóÌÐòÔ´´úÂëλÓÚÄÄÀ¡ªÈç¹ûÄãûÓÐÌṩÈκÎÖµ£¬½«Ê¹Óõ±Ç°Ä¿Â¼)¡¢Ä¿±êĿ¼(ÄãÏëÒªÉú³ÉµÄ´úÂë·ÅÔÚÄÄÀï;³£Óë $SRC_DIR Ïàͬ)£¬ÒÔ¼°ÄãµÄ .proto ·¾¶¡£ÔÚ´ËʾÀýÖУº

protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto 

ÒòΪÄãÏëÒª C++ µÄÀ࣬ËùÒÔÄãʹÓÃÁË --cpp_out Ñ¡Ï¡ªÒ²ÎªÆäËûÖ§³ÖµÄÓïÑÔÌṩÁËÀàËÆÑ¡Ïî¡£

ÔÚÄãÖ¸¶¨µÄÄ¿±êÎļþ¼Ð£¬½«Éú³ÉÒÔϵÄÎļþ£º

addressbook.pb.h£¬ÉùÃ÷ÄãÉú³ÉÀàµÄÍ·Îļþ¡£

addressbook.pb.cc£¬°üº¬ÄãµÄÀàµÄʵÏÖ¡£

Protocol Buffer API

ÈÃÎÒÃÇ¿´¿´Éú³ÉµÄһЩ´úÂ룬Á˽âһϱàÒëÆ÷ΪÄã´´½¨ÁËʲôÀàºÍº¯Êý¡£Èç¹ûÄã²é¿´ addressbook.pb.h£¬Äã¿ÉÒÔ¿´µ½ÓÐÒ»¸öÔÚ addressbook.proto ÖÐÖ¸¶¨ËùÓÐÏûÏ¢µÄÀà¡£¹Ø×¢ Person À࣬¿ÉÒÔ¿´µ½±àÒëÆ÷Ϊÿ¸ö×Ö¶ÎÉú³ÉÁ˶Áдº¯Êý(accessors)¡£ÀýÈ磬¶ÔÓÚ name¡¢id¡¢email ºÍ phone ×ֶΣ¬ÓÐÏÂÃæÕâЩ·½·¨£º(LCTT Òë×¢£º´Ë´¦Ô­ÎÄËùÖ¸ÎļþÃûÓÐÎ󣬾¶¸ÃÖ®¡£)

// name 
inline bool has_name() const;
inline void clear_name();
inline const ::std::string& name() const;
inline void set_name(const ::std::string& value);
inline void set_name(const char* value);
inline ::std::string* mutable_name();
// id
inline bool has_id() const;
inline void clear_id();
inline int32_t id() const;
inline void set_id(int32_t value);
// email
inline bool has_email() const;
inline void clear_email();
inline const ::std::string& email() const;
inline void set_email(const ::std::string& value);
inline void set_email(const char* value);
inline ::std::string* mutable_email();
// phone
inline int phone_size() const;
inline void clear_phone();
inline const ::google::protobuf::RepeatedPtrField<
::tutorial::Person_PhoneNumber >& phone() const;
inline ::google::protobuf::RepeatedPtrField<
::tutorial::Person_PhoneNumber >* mutable_phone();
inline const ::tutorial::Person_PhoneNumber& phone(int index) const;
inline ::tutorial::Person_PhoneNumber* mutable_phone(int index);
inline ::tutorial::Person_PhoneNumber* add_phone();

ÕýÈçÄãËù¼ûµ½£¬getters µÄÃû×ÖÓë×ֶεÄСдÃû×ÖÍêȫһÑù£¬²¢ÇÒ setter ·½·¨ÒÔ set_ ¿ªÍ·¡£Í¬Ê±Ã¿¸öµ¥Ò»(singular)(required »ò optional)×ֶζ¼ÓÐ has_ ·½·¨£¬¸Ã·½·¨ÔÚ×ֶα»ÉèÖÃÁËÖµµÄÇé¿öÏ·µ»Ø true¡£×îºó£¬ËùÓÐ×ֶζ¼ÓÐÒ»¸ö clear_ ·½·¨£¬ÓÃÒÔÇå³ý×ֶÕ(empty)״̬¡£

Êý×ÖÐ굀 id ×ֶνöÓÐÉÏÊöµÄ»ù±¾¶Áдº¯Êý(accessors)¼¯ºÏ£¬¶ø name ºÍ email ×Ö¶ÎÓÐÁ½¸ö¶îÍâµÄ·½·¨£¬ÒòΪËüÃÇÊÇ×Ö·û´®¡ª¡ªÒ»¸öÊÇ¿ÉÒÔ»ñµÃ×Ö·û´®Ö±½ÓÖ¸ÕëµÄmutable_ µÄ getter £¬ÁíÒ»¸öΪ¶îÍâµÄ setter¡£×¢Ò⣬¾¡¹Ü email »¹Ã»±»ÉèÖÃ(set)£¬ÄãÒ²¿ÉÒÔµ÷Óà mutable_email;ÒòΪ email »á±»×Ô¶¯µØ³õʼ»¯Îª¿Õ×Ö·û´®¡£ÔÚ±¾ÀýÖУ¬Èç¹ûÄãÓÐÒ»¸öµ¥Ò»µÄ(required »ò optional)ÏûÏ¢×ֶΣ¬Ëü»áÓÐÒ»¸ö mutable_ ·½·¨£¬¶øÃ»ÓÐ set_ ·½·¨¡£

repeated ×Ö¶ÎÒ²ÓÐÒ»Ð©ÌØÊâµÄ·½·¨¡ª¡ªÈç¹ûÄã¿´¿´ repeated µÄ phone ×ֶεķ½·¨£¬Äã¿ÉÒÔ¿´µ½£º

¼ì²é repeated ×Ö¶ÎµÄ _size(Ò²¾ÍÊÇ˵£¬Óë Person Ïà¹ØµÄµç»°ºÅÂëµÄ¸öÊý)

ʹÓÃϱêÈ¡µÃÌØ¶¨µÄµç»°ºÅÂë

¸üÐÂÌØ¶¨Ï±êµÄµç»°ºÅÂë

Ìí¼Óеĵ绰ºÅÂëµ½ÏûÏ¢ÖУ¬Ö®ºóÄã±ã¿ÉÒԱ༭¡£(repeated ±êÁ¿ÀàÐÍÓÐÒ»¸ö add_ ·½·¨£¬ÓÃÓÚ´«ÈëеÄÖµ)

ΪÁË»ñÈ¡ protocol ±àÒëÆ÷ΪËùÓÐ×ֶζ¨ÒåÉú³ÉµÄ·½·¨µÄÐÅÏ¢£¬¿ÉÒԲ鿴 C++ generated code reference¡£

ö¾ÙºÍǶÌ×Àà

Óë .proto µÄö¾ÙÏà¶ÔÓ¦£¬Éú³ÉµÄ´úÂë°üº¬ÁËÒ»¸ö PhoneType ö¾Ù¡£Äã¿ÉÒÔͨ¹ý Person::PhoneType ÒýÓÃÕâ¸öÀàÐÍ£¬Í¨¹ý Person::MOBILE¡¢Person::HOME ºÍ Person::WORK ÒýÓÃËüµÄÖµ¡£(ʵÏÖϸ½ÚÓе㸴ÔÓ£¬µ«ÊÇÄãÎÞÐëÁ˽âËüÃǶø¿ÉÒÔÖ±½ÓʹÓÃ)

±àÒëÆ÷Ò²Éú³ÉÁËÒ»¸ö Person::PhoneNumber µÄǶÌ×Àà¡£Èç¹ûÄã²é¿´´úÂ룬Äã¿ÉÒÔ·¢ÏÖÕæÕýµÄÀàÐÍΪ Person_PhoneNumber£¬µ«Ëüͨ¹ýÔÚ Person ÄÚ²¿Ê¹Óà typedef ¶¨Ò壬ʹÄã¿ÉÒÔ°Ñ Person_PhoneNumber µ±³ÉǶÌ×ÀࡣΨһ²úÉúÓ°ÏìµÄÒ»¸öÀý×ÓÊÇ£¬Èç¹ûÄãÏëÒªÔÚÆäËûÎļþǰÖÃÉùÃ÷¸ÃÀࡪ¡ªÔÚ C++ ÖÐÄã²»ÄÜǰÖÃÉùÃ÷ǶÌ×À࣬µ«ÊÇÄã¿ÉÒÔǰÖÃÉùÃ÷ Person_PhoneNumber¡£

±ê×¼µÄÏûÏ¢·½·¨

ËùÓеÄÏûÏ¢·½·¨¶¼°üº¬ÁËÐí¶à±ðµÄ·½·¨£¬ÓÃÓÚ¼ì²éºÍ²Ù×÷Õû¸öÏûÏ¢£¬°üÀ¨£º

bool IsInitialized() const; £º¼ì²éÊÇ·ñËùÓÐ required ×Ö¶ÎÒѾ­±»ÉèÖá£

string DebugString() const; £º·µ»ØÈËÀà¿É¶ÁµÄÏûÏ¢±íʾ£¬¶Ôµ÷ÊÔÌØ±ðÓÐÓá£

void CopyFrom(const Person& from);£ºÊ¹Óøø¶¨µÄÖµÖØÐ´ÏûÏ¢¡£

void Clear();£ºÇå³ýËùÓÐÔªËØÎª¿ÕµÄ״̬¡£

ÉÏÃæÕâЩ·½·¨ÒÔ¼°ÏÂÒ»½ÚÒª½²µÄ I/O ·½·¨ÊµÏÖÁ˱»ËùÓÐ C++ protocol buffer À๲ÏíµÄÏûÏ¢(Message)½Ó¿Ú¡£ÎªÁË»ñÈ¡¸ü¶àÐÅÏ¢£¬Çë²é¿´ complete API documentation for Message¡£

½âÎöºÍÐòÁл¯

×îºó£¬ËùÓÐ protocol buffer Àà¶¼ÓжÁдÄãÑ¡¶¨ÀàÐÍÏûÏ¢µÄ·½·¨£¬ÕâЩ·½·¨Ê¹ÓÃÁËÌØ¶¨µÄ protocol buffer ¶þ½øÖƸñʽ¡£ÕâЩ·½·¨°üÀ¨£º

bool SerializeToString(string* output) const;£ºÐòÁл¯ÏûÏ¢²¢½«ÏûÏ¢×Ö½ÚÊý¾Ý´æ´¢ÔÚ¸ø¶¨µÄ×Ö·û´®ÖС£×¢Ò⣬×Ö½ÚÊý¾ÝÊǶþ½øÖƸñʽµÄ£¬¶ø²»ÊÇÎı¾¸ñʽ;ÎÒÃÇֻʹÓà string Àà×÷ΪºÏÊʵÄÈÝÆ÷¡£

bool ParseFromString(const string& data);£º´Ó¸ø¶¨µÄ×Ö·û´´½âÎöÏûÏ¢¡£

bool SerializeToOstream(ostream* output) const;£º½«ÏûϢдµ½¸ø¶¨µÄ C++ ostream¡£

bool ParseFromIstream(istream* input);£º´Ó¸ø¶¨µÄ C++ istream ½âÎöÏûÏ¢¡£

ÕâЩֻÊÇÁ½¸öÓÃÓÚ½âÎöºÍÐòÁл¯µÄÑ¡Ôñ¡£ÔÙ´Î˵Ã÷£¬¿ÉÒԲ鿴 Message API reference ÍêÕûµÄÁÐ±í¡£

Protocol Buffers ºÍÃæÏò¶ÔÏóÉè¼Æ

Protocol buffer Ààͨ³£Ö»ÊÇ´¿´âµÄÊý¾Ý´æ´¢Æ÷(Ïñ C++ ÖеĽṹÌå);ËüÃÇÔÚ¶ÔÏóÄ£ÐÍÖв¢²»ÊÇÒ»µÈ¹«Ãñ¡£Èç¹ûÄãÏëÏòÉú³ÉµÄ protocol buffer ÀàÖÐÌí¼Ó¸ü·á¸»µÄÐÐΪ£¬×îºÃµÄ·½·¨¾ÍÊÇÔÚÓ¦ÓóÌÐòÖжÔËü½øÐзâ×°¡£Èç¹ûÄãÎÞȨ¿ØÖÆ .proto ÎļþµÄÉè¼ÆµÄ»°£¬·â×° protocol buffers Ò²ÊÇÒ»¸öºÃÖ÷Òâ(ÀýÈ磬Äã´ÓÁíÒ»¸öÏîÄ¿ÖÐÖØÓÃÒ»¸ö .proto Îļþ)¡£ÔÚÄÇÖÖÇé¿öÏ£¬Äã¿ÉÒÔÓ÷â×°ÀàÀ´Éè¼Æ½Ó¿Ú£¬ÒÔ¸üºÃµØÊÊÓ¦ÄãµÄÓ¦ÓóÌÐòµÄÌØ¶¨»·¾³£ºÒþ²ØÒ»Ð©Êý¾ÝºÍ·½·¨£¬±©Â¶Ò»Ð©±ãÓÚʹÓõĺ¯Êý£¬µÈµÈ¡£µ«ÊÇÄã¾ø¶Ô²»ÒªÍ¨¹ý¼Ì³ÐÉú³ÉµÄÀàÀ´Ìí¼ÓÐÐΪ¡£ÕâÑù×öµÄ»°£¬»áÆÆ»µÆäÄÚ²¿»úÖÆ£¬²¢ÇÒ²»ÊÇÒ»¸öºÃµÄÃæÏò¶ÔÏóµÄʵ¼ù¡£

дÏûÏ¢

ÏÖÔÚÎÒÃdz¢ÊÔʹÓà protocol buffer Àà¡£ÄãµÄµØÖ·²¾³ÌÐòÏëÒª×öµÄµÚÒ»¼þÊÂÊǽ«¸öÈËÏêϸÐÅϢдÈëµ½µØÖ·²¾Îļþ¡£ÎªÁË×öµ½ÕâÒ»µã£¬ÄãÐèÒª´´½¨¡¢Ìî³ä protocol buffer ÀàʵÀý£¬²¢ÇÒ½«ËüÃÇдÈëµ½Ò»¸öÊä³öÁ÷(output stream)¡£

ÕâÀïµÄ³ÌÐò¿ÉÒÔ´ÓÎļþ¶ÁÈ¡ AddressBook£¬¸ù¾ÝÓû§ÊäÈ룬½«Ð Person Ìí¼Óµ½ AddressBook£¬²¢ÇÒÔٴν«Ð嵀 AddressBook д»ØÎļþ¡£Õⲿ·ÖÖ±½Óµ÷ÓûòÒýÓà protocol buffer ÀàµÄ´úÂë»áÒÔ¡°// pb¡±±ê³ö¡£

#include <iostream> 
#include <fstream>
#include <string>
#include "addressbook.pb.h" // pb
using namespace std;
// This function fills in a Person message based on user input.
void PromptForAddress(tutorial::Person* person) {
cout << "Enter person ID number: ";
int id;
cin >> id;
person->set_id(id); // pb
cin.ignore(256, '\n');
cout << "Enter name: ";
getline(cin, *person->mutable_name()); // pb
cout << "Enter email address (blank for none): ";
string email;
getline(cin, email);
if (!email.empty()) { // pb
person->set_email(email); // pb
}
while (true) {
cout << "Enter a phone number (or leave blank to finish): ";
string number;
getline(cin, number);
if (number.empty()) {
break;
}
tutorial::Person::PhoneNumber* phone_number = person->add_phone(); //pb
phone_number->set_number(number); // pb
cout << "Is this a mobile, home, or work phone? ";
string type;
getline(cin, type);
if (type == "mobile") {
phone_number->set_type(tutorial::Person::MOBILE); // pb
} else if (type == "home") {
phone_number->set_type(tutorial::Person::HOME); // pb
} else if (type == "work") {
phone_number->set_type(tutorial::Person::WORK); // pb
} else {
cout << "Unknown phone type. Using default." << endl;
}
}
}
// Main function: Reads the entire address book from a file,
// adds one person based on user input, then writes it back out to the same
// file.
int main(int argc, char* argv[]) {
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION; // pb
if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
return -1;
}
tutorial::AddressBook address_book; // pb
{
// Read the existing address book.
fstream input(argv[1], ios::in | ios::binary);
if (!input) {
cout << argv[1] << ": File not found. Creating a new file." << endl;
} else if (!address_book.ParseFromIstream(&input)) { // pb
cerr << "Failed to parse address book." << endl;
return -1;
}
}
// Add an address.
PromptForAddress(address_book.add_person()); // pb
{
// Write the new address book back to disk.
fstream output(argv[1], ios::out | ios::trunc | ios::binary);
if (!address_book.SerializeToOstream(&output)) { // pb
cerr << "Failed to write address book." << endl;
return -1;
}
}
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary(); // pb
return 0;
}

×¢Òâ GOOGLE_PROTOBUF_VERIFY_VERSION ºê¡£ËüÊÇÒ»ÖֺõÄʵ¼ù¡ª¡ªËäÈ»²»ÊÇÑϸñ±ØÐëµÄ¡ª¡ªÔÚʹÓà C++ Protocol Buffer ¿â֮ǰִÐиúꡣËü¿ÉÒÔ±£Ö¤±ÜÃⲻСÐÄÁ´½Óµ½Ò»¸öÓë±àÒëµÄÍ·Îļþ°æ±¾²»¼æÈÝµÄ¿â°æ±¾¡£Èç¹û±»¼ì²é³öÀ´°æ±¾²»Æ¥Å䣬³ÌÐò½«»áÖÕÖ¹¡£×¢Ò⣬ÿ¸ö .pb.cc ÎļþÔÚ³õʼ»¯Ê±»á×Ô¶¯µ÷ÓÃÕâ¸öºê¡£

ͬʱעÒâÔÚ³ÌÐò×îºóµ÷Óà ShutdownProtobufLibrary()¡£ËüÓÃÓÚÊÍ·Å Protocol Buffer ¿âÉêÇëµÄËùÓÐÈ«¾Ö¶ÔÏ󡣶Դ󲿷ֳÌÐò£¬Õâ²»ÊDZØÐëµÄ£¬ÒòΪËäÈ»³ÌÐòÖ»ÊǼòµ¥Í˳ö£¬µ«ÊÇ OS »á´¦ÀíÊͷųÌÐòµÄËùÓÐÄڴ档Ȼ¶ø£¬Èç¹ûÄãʹÓÃÁËÄÚ´æÐ¹Â©¼ì²â¹¤¾ß£¬¹¤¾ßÒªÇóÈ«²¿¶ÔÏó¶¼ÒªÊÍ·Å£¬»òÕßÄãÕýÔÚдһ¸ö Protocol Buffer ¿â£¬¸Ã¿â¿ÉÄܻᱻһ¸ö½ø³Ì¶à´Î¼ÓÔØºÍÐ¶ÔØ£¬ÄÇôÄã¿ÉÄÜÐèÒªÇ¿ÖÆ Protocol Buffer Çå³ýËùÓж«Î÷¡£

¶ÁÈ¡ÏûÏ¢

µ±È»£¬Èç¹ûÄãÎÞ·¨´ÓËü»ñÈ¡ÈκÎÐÅÏ¢£¬ÄÇôÕâ¸öµØÖ·²¾Ã»¶à´óÓô¦!Õâ¸öʾÀý¶ÁÈ¡ÉÏÃæÀý×Ó´´½¨µÄÎļþ£¬²¢´òÓ¡ÎļþÀïµÄËùÓÐÄÚÈÝ¡£

#include <iostream> 
#include <fstream>
#include <string>
#include "addressbook.pb.h" // pb
using namespace std;
// Iterates though all people in the AddressBook and prints info about them.
void ListPeople(const tutorial::AddressBook& address_book) { // pb
for (int i = 0; i < address_book.person_size(); i++) { // pb
const tutorial::Person& person = address_book.person(i); // pb
cout << "Person ID: " << person.id() << endl; // pb
cout << " Name: " << person.name() << endl; // pb
if (person.has_email()) { // pb
cout << " E-mail address: " << person.email() << endl; // pb
}
for (int j = 0; j < person.phone_size(); j++) { // pb
const tutorial::Person::PhoneNumber& phone_number = person.phone(j); // pb
switch (phone_number.type()) { // pb
case tutorial::Person::MOBILE: // pb
cout << " Mobile phone #: ";
break;
case tutorial::Person::HOME: // pb
cout << " Home phone #: ";
break;
case tutorial::Person::WORK: // pb
cout << " Work phone #: ";
break;
}
cout << phone_number.number() << endl; // ob
}
}
}
// Main function: Reads the entire address book from a file and prints all
// the information inside.
int main(int argc, char* argv[]) {
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION; // pb
if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
return -1;
}
tutorial::AddressBook address_book; // pb
{
// Read the existing address book.
fstream input(argv[1], ios::in | ios::binary);
if (!address_book.ParseFromIstream(&input)) { // pb
cerr << "Failed to parse address book." << endl;
return -1;
}
}
ListPeople(address_book);
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary(); // pb
return 0;
}

À©Õ¹ Protocol Buffer

»òÔç»òÍíÔÚÄã·¢²¼ÁËʹÓà protocol buffer µÄ´úÂëÖ®ºó£¬ºÁÎÞÒÉÎÊ£¬Äã»áÏëÒª "¸ÄÉÆ" protocol buffer µÄ¶¨Òå¡£Èç¹ûÄãÏëÒªÐ嵀 buffers Ïòºó¼æÈÝ£¬²¢ÇÒÀ쵀 buffers Ïòǰ¼æÈÝ¡ª¡ª¼¸ºõ¿ÉÒԿ϶¨ÄãºÜ¿ÊÍûÕâ¸ö¡ª¡ªÕâÀïÓÐһЩ¹æÔò£¬ÄãÐèÒª×ñÊØ¡£ÔÚÐ嵀 protocol buffer °æ±¾£º

Äã¾ø²»¿ÉÒÔÐÞ¸ÄÈκÎÒÑ´æÔÚ×ֶεıêÇ©Êý×Ö

Äã¾ø²»¿ÉÒÔÌí¼Ó»òɾ³ýÈκΠrequired ×Ö¶Î

Äã¿ÉÒÔɾ³ý optional »ò repeated ×Ö¶Î

Äã¿ÉÒÔÌí¼ÓÐ嵀 optional »ò repeated ×ֶΣ¬µ«ÊÇÄã±ØÐëʹÓÃеıêÇ©Êý×Ö(Ò²¾ÍÊÇ˵£¬±êÇ©Êý×ÖÔÚ protocol buffer ÖдÓδʹÓùý£¬ÉõÖÁ²»ÄÜÊÇÒÑɾ³ý×ֶεıêÇ©Êý×Ö)¡£

(¶ÔÓÚÉÏÃæ¹æÔòÓÐһЩÀýÍâÇé¿ö£¬µ«ËüÃǺÜÉÙÓõ½¡£)

Èç¹ûÄãÄÜ×ñÊØÕâЩ¹æÔò£¬¾É´úÂëÔò¿ÉÒÔ»¶¿ìµØ¶ÁȡеÄÏûÏ¢£¬²¢ÇÒ¼òµ¥µØºöÂÔËùÓÐеÄ×ֶΡ£¶ÔÓھɴúÂëÀ´Ëµ£¬±»É¾³ýµÄ optional ×ֶν«»á¼òµ¥µØ¸³ÓèĬÈÏÖµ£¬±»É¾³ýµÄ repeated ×ֶλáΪ¿Õ¡£Ð´úÂëÏÔÈ»¿ÉÒÔ¶ÁÈ¡¾ÉÏûÏ¢¡£È»¶ø£¬Çë¼ÇסÐ嵀 optional ×ֶβ»»á³ÊÏÖÔÚ¾ÉÏûÏ¢ÖУ¬Òò´ËÄãÐèÒªÏÔʽµØÊ¹Óà has_ ¼ì²éËüÃÇÊÇ·ñ±»ÉèÖûòÕßÔÚ .proto ÎļþÔÚ±êÇ©Êý×ÖºóʹÓà [default = value] Ìṩһ¸öºÏÀíµÄĬÈÏÖµ¡£Èç¹ûÒ»¸ö optional ÔªËØÃ»ÓÐÖ¸¶¨Ä¬ÈÏÖµ£¬Ëü½«»áʹÓÃÀàÐÍÌØ¶¨µÄĬÈÏÖµ£º¶ÔÓÚ×Ö·û´®£¬Ä¬ÈÏֵΪ¿Õ×Ö·û´®;¶ÔÓÚ²¼¶ûÖµ£¬Ä¬ÈÏֵΪ false;¶ÔÓÚÊý×ÖÀàÐÍ£¬Ä¬ÈÏÀàÐÍΪ 0¡£×¢Ò⣬Èç¹ûÄãÌí¼ÓÒ»¸öÐ嵀 repeated ×ֶΣ¬Ð´úÂ뽫ÎÞ·¨±æ±ðËü±»Áô¿Õ(±»Ð´úÂë)»òÕß´Óû±»ÉèÖÃ(±»¾É´úÂë)£¬ÒòΪ repeated ×Ö¶ÎûÓÐ has_ ±êÖ¾¡£

ÓÅ»¯¼¼ÇÉ

C++ Protocol Buffer ¿âÒѼ«¶ÈÓÅ»¯¹ýÁË¡£µ«ÊÇ£¬Ç¡µ±µÄÓ÷¨Äܹ»¸ü¶àµØÌá¸ßÐÔÄÜ¡£ÕâÀïÊÇһЩ¼¼ÇÉ£¬¿ÉÒÔ°ïÄã´Ó¿âÖм·Ñ¹³ö×îºóÒ»µãËÙ¶È£º

¾¡¿ÉÄܸ´ÓÃÏûÏ¢¶ÔÏó¡£¼´Ê¹ËüÃDZ»Çå³ýµô£¬ÏûÏ¢Ò²»á¾¡Á¿±£´æËùÓб»·ÖÅäÀ´ÖØÓõÄÄÚ´æ¡£Òò´Ë£¬Èç¹ûÎÒÃÇÕýÔÚ´¦ÀíÐí¶àÏàͬÀàÐÍ»òһϵÁÐÏàËÆ½á¹¹µÄÏûÏ¢£¬Ò»¸öºÃµÄ°ì·¨ÊÇÖØÓÃÏàͬµÄÏûÏ¢¶ÔÏ󣬴Ӷø¼õÉÙÄÚ´æ·ÖÅäµÄ¸ºµ£¡£µ«ÊÇ£¬Ëæ×Åʱ¼äµÄÁ÷ÊÅ£¬¶ÔÏó¿ÉÄÜ»áÅòÕͱä´ó£¬ÓÈÆäÊǵ±ÄãµÄÏûÏ¢³ß´ç(LCTT Òë×¢£º¸÷ÏûÏ¢ÄÚÈݲ»Í¬£¬ÓÐЩÏûÏ¢ÄÚÈݶàһЩ£¬ÓÐЩÏûÏ¢ÄÚÈÝÉÙһЩ)²»Í¬µÄʱºò£¬»òÕßÄãż¶û´´½¨ÁËÒ»¸ö±Èƽ³£´óºÜ¶àµÄÏûÏ¢µÄʱºò¡£ÄãÓ¦¸Ã×Ô¼ºÍ¨¹ýµ÷Óà SpaceUsed ·½·¨¼à²âÏûÏ¢¶ÔÏóµÄ´óС£¬²¢ÔÚËüÌ«´óµÄʱºòɾ³ýËü¡£

¶ÔÓÚÔÚ¶àÏß³ÌÖзÖÅä´óÁ¿Ð¡¶ÔÏóµÄÇé¿ö£¬ÄãµÄ²Ù×÷ϵͳÄÚ´æ·ÖÅäÆ÷¿ÉÄÜÓÅ»¯µÃ²»¹»ºÃ¡£Äã¿ÉÒÔ³¢ÊÔʹÓà google µÄ tcmalloc¡£

¸ß¼¶Ó÷¨

Protocol Buffers ¾ø²»½öÓÃÓÚ¼òµ¥µÄÊý¾Ý´æÈ¡ÒÔ¼°ÐòÁл¯¡£ÇëÔĶÁ C++ API reference À´¿´¿´Ä㻹ÄÜÓÃËüÀ´×öʲô¡£

protocol ÏûÏ¢ÀàËùÌṩµÄÒ»¸ö¹Ø¼üÌØÐÔ¾ÍÊÇ·´Éä(reflection)¡£Äã²»ÐèÒªÕë¶ÔÒ»¸öÌØÊâµÄÏûÏ¢ÀàÐͱàд´úÂ룬¾Í¿ÉÒÔ±éÀúÒ»¸öÏûÏ¢µÄ×ֶβ¢²Ù×÷ËüÃǵÄÖµ¡£Ò»¸öʹÓ÷´ÉäµÄÓÐÓ÷½·¨ÊÇ protocol ÏûÏ¢ÓëÆäËû±àÂ뻥Ïàת»»£¬±ÈÈç XML »ò JSON¡£·´ÉäµÄÒ»¸ö¸ü¸ß¼¶µÄÓ÷¨¿ÉÄܾÍÊÇ¿ÉÒÔÕÒ³öÁ½¸öÏàͬÀàÐ͵ÄÏûÏ¢Ö®¼äµÄÇø±ð£¬»òÕß¿ª·¢Ä³ÖÖ¡°Ð­ÒéÏûÏ¢µÄÕýÔò±í´ïʽ¡±£¬ÀûÓÃÕýÔò±í´ïʽ£¬Äã¿ÉÒÔ¶ÔijÖÖÏûÏ¢ÄÚÈݽøÐÐÆ¥Åä¡£Ö»ÒªÄã·¢»ÓÄãµÄÏëÏñÁ¦£¬¾ÍÓпÉÄܽ« Protocol Buffers Ó¦Óõ½Ò»¸ö¸ü¹ã·ºµÄ¡¢Äã¿ÉÄÜÒ»¿ªÊ¼¾ÍÆÚÍû½â¾öµÄÎÊÌⷶΧÉÏ¡£

   
1993 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]
Visual C++±à³ÌÃüÃû¹æÔò
ÈκÎʱºò¶¼ÊÊÓõÄ20¸öC++¼¼ÇÉ
CÓïÑÔ½ø½×
´®¿ÚÇý¶¯·ÖÎö
ÇáÇáËÉËÉ´ÓCһ·×ßµ½C++
C++±à³Ì˼Ïë


C++²¢·¢´¦Àí+µ¥Ôª²âÊÔ
C++³ÌÐò¿ª·¢
C++¸ß¼¶±à³Ì
C/C++¿ª·¢
C++Éè¼ÆÄ£Ê½
C/C++µ¥Ôª²âÊÔ


±±¾© ǶÈëʽC¸ßÖÊÁ¿±à³Ì
Öйúº½¿Õ ǶÈëʽC¸ßÖÊÁ¿±à³Ì
»ªÎª C++¸ß¼¶±à³Ì
±±¾© C++¸ß¼¶±à³Ì
µ¤·ð˹ C++¸ß¼¶±à³Ì
±±´ó·½Õý CÓïÑÔµ¥Ôª²âÊÔ
ÂÞ¿ËΤ¶û C++µ¥Ôª²âÊÔ