En mi opinión, no es tanto un problema de definición como un problema de usabilidad.
Los objetos son una abstracción destinada a facilitar la lectura, escritura y razonamiento sobre programas complejos. Para un programador práctico, si un lenguaje cumple con todos los criterios de una definición formal particular de "orientado a objetos" (¡parece que hay varios competidores!) No es realmente tan importante como si las herramientas que ofrece son adecuadas para pensar su programa en términos de dichos objetos, es decir, cosechar los supuestos beneficios de productividad de OOP.
En C ++, los objetos son abstracciones con fugas terribles , que a menudo obligan a los programadores a lidiar con problemas desagradables relacionados con la forma en que esos objetos están estructurados en la memoria, problemas que recuerdan más la codificación en C directo que otros lenguajes OOP. Por ejemplo, C ++ Respuestas a preguntas frecuentes ofrece esta crítica (entre otras):
Es muy beneficioso para un profesional familiarizarse con los sistemas OO que no sean C ++, y con las definiciones OO que no sean la trinidad de "encapsulación, herencia, polimorfismo" interpretada de maneras especiales que permitan que C ++ se considere "OO". Por ejemplo, una afirmación de que un entorno que carece de verificación de límites o recolección de basura no es un entorno OO parece indignante para las personas acostumbradas a C ++. Pero desde muchas perspectivas, tiene mucho sentido. Si alguien puede sobrescribir un objeto, ¿dónde está la "encapsulación"? Si desechar un objeto puede provocar referencias colgantes o pérdidas de memoria, ¿cómo está el sistema "orientado a objetos"? ? ¿Qué pasa con la capacidad de saber qué tipo de objeto se encuentra en un lugar y hora determinados? Dices que el software funciona con objetos, ¿dónde están? Y si uno no puede averiguarlo, ¿cómo se supone que se debe depurar el software?
C ++ está orientado a objetos, pero de manera desagradable e incompleta: sus usuarios tienen que dedicar mucho esfuerzo para asegurarse de que sus datos realmente se comporten como objetos "reales" en lugar de bits errantes. Dicho esto, se ha escrito mucho código en C ++ a lo largo de su vida útil, la mayor parte haciendo uso de clases y despacho dinámico, por lo que es evidentemente algo que puede usar para la OOP práctica.