2009-11-06 6 views
5

Como en el ejemplo a continuación, ¿qué está permitido, cómo y por qué?¿Qué es lo que C++ gobierna con respecto a los tipos de retorno covariantes?

class Shape { 
     public: 
     //... 
     virtual Shape *clone() const = 0; // Prototype 
     //... 
    }; 
    class Circle : public Shape { 
     public: 
     Circle *clone() const; 
     //... 
    }; 
+2

¿Cuál es exactamente la pregunta? Si conoce el término * covariante *, entonces probablemente sepa lo que significa. Entonces, la respuesta es: se permiten los tipos de retorno covariantes. Eso es. – AnT

+0

Solo un enlace para personas que no estén familiarizadas con el tipo de retorno covariante: http://en.wikipedia.org/wiki/Covariant_return_type –

+1

Regla # 1 de declaraciones covariantes: no use VC6. –

Respuesta

10

C++ Standard 2003. 10.3.5

El tipo de retorno de una función primordial será, o bien idéntica a el tipo de retorno de la función se reemplaza o covariante con las clases de las funciones. Si una función f D :: se impone a una función B :: f, el retorno tipos de las funciones son covariantes si cumplen los siguientes criterios:

- ambos son punteros a clases o referencias a clases

- la clase en el tipo de retorno de B :: f es la misma clase que la clase en el tipo de retorno de D :: f, o es una clase inequívoca y accesible directa o de base indirecta de la clase en el tipo de devolución de D :: f

- ambos punteros o referencias tienen el mismo cv-calificación y el tipo clase en el tipo de retorno de D :: f tiene el mismo cv-calificación como o menos cv-calificación que el tipo de clase en el tipo de devolución de B :: f.

Si el tipo de retorno de D :: f difiere del tipo de retorno de B :: f, del tipo clase en el tipo de retorno de D :: f será completa en el punto de declaración de D :: f o será el tipo clase D. Cuando la función primordial se llama como la final overrider de la función reemplazada, su resultado se convierte en el tipo devuelto por el (estáticamente elegido) función reemplazada (5,2 .2).

Ejemplo:

class B {}; 
class D : private B { friend class Derived; }; 
struct Base { 
    virtual B* vf4(); 
    virtual B* vf5(); 
}; 
class A; 
struct Derived : public Base { 
    D* vf4(); // OK: returns pointer to derived class 
    A* vf5(); // error: returns pointer to incomplete class 
}; 
4

Pff, demasiado largo estándar citando.

Puede utilizar otro tipo como covariante si (a) es un puntero/referencia (b) se puede convertir al tipo de devolución anterior por la mera adición de una constante conocida en el tiempo de compilación (c) es compatible con todos los calificadores constantes-volátiles.

+0

Tal vez (b) necesitaría alguna aclaración adicional.No es demasiado común definir las versiones en términos de constantes de tiempo de compilación –

+0

Para una mayor aclaración, otra publicación sirve mejor –

Cuestiones relacionadas