سي++ مزايا اللغة
يمكن للتابع العضو أن يكون «ظاهرياً صرفاً» (بالإنجليزية: pure virtual) من خلال إضافة 0= في نهاية التصريح عن التابع وقبل الفاصلة المنقوطة. يسمى الصف الذي يحتوي تابعاً عضواً ظاهرياً صرفاً واحداً على الأقل باسم نمط بيانات مجرد. لا يمكن إنشاء كائنات من أنماط البيانات المجردة. يمكن فقط اشتقاق أنماط البيانات المجردة. أي صف مشتق يرث تابعاً ظاهرياً صرفاً (أو أكثر) يجب أن يوفر تعريفاً غير-صرفٍ له لكي يمكن إنشاء كائنات منه. أي برنامج يحاول إنشاء كائنات من صف يحوي تابعاً ظاهرياً صرفاً أو يرث تابعاً ظاهرياً صرفاً (دون توفير تعريف غير-صرف له) هو برنامج سيئ التشكيل (بالإنجليزية: ill-formed) بالنسبة لقواعد كتابة برنامج باستخدام ++C.
إن كتابة مجزئ باستخدام إحدى خوارزميات التجزيء الكلاسيكية كخوارزمية المجزئ يسار يمين أمامي (1)LALR مهمة صعبة نسبياً. يعود السبب في ذلك جزئياً إلى أن قواعد لغة ++C ليست في الحقيقة LALR. نتيجة ذلك يوجد عدد محدود جداً من الأدوات القادرة على معالجة الكود وإجراء تحويلات غير بديهية عليه (كإعادة هيكلة الكود مثلاً). إحدى طرق التغلب على هذه الصعوبة تمكن في اختيار نحو مختلف. يمكن لبعض المجزئات الفعالة مثل مجزئ يسار يمين المعمم القيام بتجزئة الكود بسهولة (إلا أنها أبطأ).
إن التجزيء (بمعنى بناء شجرة نحوية) ليس أصعب المهام اللازمة لبناء أداة معالجة كود ++C. إذ يجب على أدوات كهذه الإلمام بمعاني المعرّفات المستخدمة في البرنامج تماماً كما يفعل المصرف. يجب على الأنظمة الفعالة التي تعالج كود ++C أن لا تقوم فقط بتجزيء النص المصدري، بل يجب عليها أيضاً أن تنسب كل معرف إلى التعريف المناسب له تماماً وفق السياق (على سبيل المثال يجب عليها أن تتعامل بشكل صحيح مع قواعد نطاقات التسمية المعقدة) كما يجب عليها أن تقرر نمط المعرف وكذلك أنماط التعابير المركبة.
أخيراً يجب أن تستطيع أداة معالجة كود ++C التعامل مع عدد من لهجات ++C المستخدمة بشكل شائع (مثل تلك المدعومة من قبل GNU Compiler Collection و++Microsoft Visual C) وأن توفر المحللات وتحويلات الكود وإعادة توليد الكود المصدري المناسب لها. إن الدمج بين خوارزميات المتطورة مثل خوارزمية مجزئ يسار يمين المعمم مع جداول الرموز وتقنية تحويل النصوص المصدرية يتيح بناء كافة أدوات معالجة ++C. توفر جميع المصرفات أدواتاً للتجزيء. على الرغم من أن هنالك مصرف وحيد فقط يوفر مجزئاً يتمتع بالمرونة الكافية لدمجه مع أدوات الأخرى وهو Clang حيث يمكن استخدام المجزئ الخاص به كمكتبة ++C (أو C) جاهزة للاندماج في أدوات أخرى كبيئة تطوير متكاملة مثلاً.
يواجه منتجو المصرفات صعوبات جمة في بناء مصرف متوافق بشكل كامل مع معيار ++C. فقد طبقت العديد من المصرفات لسنواتٍ كثيرة لغة ++C بمستويات متفاوتة من ناحية التوافق مع المعيار، وقد اختلفت أساليب تحقيق بعض جوانب اللغة مثل تخصيص القوالب الجزئي فيما بينها إلى درجة عالية. تدعم الإصدارات الحديثة لمعظم مصرفات ++C الشهيرة أغلبية معيار C++ 1998.
لم تملِ لجنة معيار ++C كيفية تحقيق تغيير أسماء الرموز ومعالجة الاستثناءات ومزايا أخرى متعلقة بالتحقيق بهدف إعطاء منتجي المصرفات حرية أكبر في بناء مصرفاتهم. إن الجانب السلبي من هذا القرار هو أن الكود الكائني الذي تنتجه المصرفات المختلفة سيكون مختلفاً وغير متوافق على الأغلب. مع ذلك كان هناك عدة محاولات لتعيير المصرفات التي تعمل على أجهزة وأنظمة تشغيل محددة (على سبيل المثال مقاربة C++ ABI ) على الرغم من أن أغلبها يبدو مهملاً الآن.
تعتبر الكلمة المفتاحية export إحدى النقاط التي ساد حولها خلاف كبير. تهدف هذه الكلمة المفتاحية إلى إتاحة إمكانية فصل التصريح عن القوالب عن تعريفها. تأخر تحقيق هذه الميزة حتى عام 2003، أي بعد خمس سنوات من نشر المعيار، وكان ++Cameau C/C أول مصرف يقوم بذلك؛ خلال عام 2004 طُرحت النسخة بيتا من المصرف Borland C++ Builder X مع دعم للكلمة المفتاحية export. كلا المصرفان مبنيان على الواجهة الأمامية من المصرف ++EDG C. في حين لا تدعم العديد من المصرفات كـGCC هذه الميزة أساساً.
في كتاب ++Beginning ANSI C يقدم المؤلف إيفور هورتون مثالاً عن كود ++C يستخدم فيه هذه الكلمة المفتاحية بحيث لا يعمل على أغلب المصرفات دون الإشارة صراحة إلى السبب في ذلك. لقد أوصى المدير السابق للجنة معيار ++C هيرب شتر إلى ضرورة إزالة هذه الكلمة المفتاحية من الإصدارات المستقبلية لمعيار ++C بهدف حسم هذه المعضلة بشكل نهائي. وبالفعل فقد قررت لجنة معيار ++C خلال اجتماعها في 10 آذار 2010 إزالة مفهوم القوالب المصدّرة بشكل كامل من المعيار C++11 إلا أنها قررت الإبقاء على الكلمة المفتاحية export من أجل الاستعمال المستقبلي.
غالباً ما يتم اعتبار لغة ++C أنها تشتمل على لغة C إلا أن هذا الاعتبار ليس تام الصحة. من الممكن القيام بتصريف أغلب الكود المكتوب بلغة C ضمن بيئة ++C بشكل صحيح إلا أن هذا لا ينفي وجود بعض الاختلافات التي تجعل بعض الكود المكتوب بشكل شرعي بلغة C غير صحيح أو مختلف الأداء ضمن بيئة ++C.
أحد الاختلافات الشهيرة بين اللغتين هو قيام لغة C بالتحويل ضمنياً للنمط *void إلى أنماط مؤشرات أخرى في حين لا تقوم ++C بذلك (بهدف تعزيز ميزة التنميط الآمن). توجد أيضاً مشكلات في المحمولية بين اللغتين إذ تعرف لغة ++C العديد من الكلمات المفتاحية الجديدة مثل new وclass والتي يمكن استخدامها كمعرّفات (أسماء متحولات على سبيل المثال) في برنامج مكتوب بلغة C.
لقد أزيلت بعض عقبات عدم التوافقية في تنقيح معيار لغة C (المسمى C99) الذي تم عام 1999، حيث أضيفت بعض ميزات ++C إلى لغة C كالتعليقات السطرية (//) وإمكانية الدمج بين التصاريح وبقية أجزاء الكود. في نفس الوقت أدخل المعيار C99 عدداً من الميزات الجديدة التي لا تدعمها لغة ++C مسببة عدم التوافق أو أنها موجودة في لغة ++C ولكن بأسلوب آخر مسببة زيادةً غير مرغوبة، على سبيل المثال تعرف C99 النمط complex المعرف بلغة ++C بالصف complex الموجود ضمن مكتبة ++C القياسية، كذلك دعم C99 للمصفوفات ذات الأبعاد المتغيرة وتعريفها النمط boolean كـاسم مستعار بـtypedef في حين أنه نمط بيانات أساسي في لغة ++C، إضافة إلى إضافة الكلمة المفتاحية restrict. أٌدخلت بعض ميزات C99 الجديدة في الإصدار التالي من معيار ++C وهو C++11:
إن دمج كود C مع كود ++C يتطلب أن يسبق تصريح أي تابع يتم التعامل معه من اللغتين معلومةً تشير إلى ضرورة استخدام C للقيام بربطه مع بقية البرنامج (يتم ذلك عبر استخدام {*...*} "extern "C) تفادياً لاستخدام تقنية ربط ++C التي تغير اسم التابع (بهدف تمييز التوابع المحملة بشكل زائد عن بعضها).