2010-09-15 28 views
7

Al diseñar una API pública, ¿es una buena práctica hacer que el constructor sea explícito?¿Es una buena práctica hacer que el constructor sea explícito?

class A { 
public: 
    //explicit A(int i){} 
    A(int i){} 
}; 

void fun(const A& a) {} 

int main() { 
    // If I use explicit for A constructor, I can prevent this mistake. 
    // (Or shall I call it as feature?) 
    fun(10); 
} 

¿O debo permitir la conversión implícita, para permitir que el usuario llame a mi API con menos tipeo?

Respuesta

9

El constructor debe ser explícito, a menos que una conversión implícita tenga sentido semánticamente (por ejemplo, ¿cuál es el significado de convertir un int en un A?). Menos tipeo no debe ser el criterio para guiar esa decisión. Piense en la legibilidad (que es el argumento principal para el casting implícito) y qué tan bien debe entender su código. Un elenco implícito que no sea intuitivo hará que los lectores del código se rasquen la cabeza.

P.S .: Parece que no puedo encontrar un buen ejemplo en este momento, por lo que cualquier ayuda es apreciada.

+7

ejemplo de conversión implícita: any numberlikelike (p. Ej.una biblioteca bignum, o una biblioteca de fecha/hora) - contra la conversión implícita: simplemente considere la clase 'std :: vector' que se puede inicializar con un tamaño inicial. –

+1

Estoy de acuerdo con esto. IME rara vez hay un caso en el que desee un casting implícito y si se equivoca en el lado explícito, no se hace daño al forzar a los usuarios a unas pocas pulsaciones más. – sbi

+0

Como ejemplo: la conversión implícita de doble a complejo a través de 'complex (double re, double im = 0)' tiene sentido, pero la conversión de int a vector a través de 'vector (int size)' no. –

1

Los constructores explícitos se usan en clases que consumen recursos importantes, como memoria, tiempo de construcción, etc., para evitar que el usuario cree instancias de dichas clases accidentalmente. Depende de usted decidir si su clase es lo suficientemente "pesada" como para usar un constructor explícito.

+5

La fusión accidental puede ser fatal incluso si el objeto no es costoso de crear. –

+0

@ Space_C0wb0y: el casting accidental es tu culpa por haber tipeado accidentalmente un yeso. La conversión implícita accidental es el problema aquí, seguramente. –

+0

@Steve Jessop: Estás en lo cierto. –

1

Depende de los costos involucrados, tanto semánticamente como de rendimiento. Si la creación de su clase es costosa, debe evitar que se cree una instancia accidental. Si es una clase barata de crear, la construcción implícita puede simplificar en gran medida el trabajo para el usuario API.

+1

Esto no menciona las ambigüedades y las conversiones no sensuales y no deseadas que de otro modo podrían ocurrir. –

4

This es lo que he encontrado en un resonse de "Daniel Krugler"

Si hubiéramos comenzado a diseñar C++ a partir de hoy, hay una buena oportunidad, que todos los constructores y funciones de conversión fueron "explícitos" de forma predeterminada, pero un usuario podría hacer que el sea "implícito". Por desgracia, el tiempo no puede ser vuelto atrás y tenemos que vivir con el estado actual. Esto significa que debemos tener cuidado con respecto a los constructores implícitos (excepto para el constructor de copiar/mover ). Es una regla más segura para hacer que los constructores sean explícitos, donde está implicada alguna forma de conversión (es decir, cualquier constructor con un tipo de argumento U diferente del tipo real T).

+2

¿Quién es Daniel Krügler? –

+0

@Yan Cheng CHEOK: Supongo que es parte del comité de estándares de C++ (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010) – Chubsdad

5

Sí, de forma predeterminada cualquier constructor, que se puede llamar con un argumento debe ser explícito. Seguir esta regla evitará errores sutiles, que son extremadamente difíciles de encontrar.

Por supuesto, hay excepciones a esta regla:

  • conversión implícita podría ser deseable, si su clase tiene los semántica de una envoltura alrededor de tipo uno del parámetro.

  • Los constructores de copia no deben ser explícitos (de lo contrario, perderá la posibilidad de para las llamadas de valor por paso).

+0

+1, pero agregaría credibilidad si usted ilustró dichos errores. –

Cuestiones relacionadas