C ++ Primer quinto notas (capítulo 14 operación de sobrecarga y conversión de tipo) conversión de tipo de ambigüedad

1. Habrá ambigüedad en dos situaciones:

1.1 La clase A define un constructor de conversión que acepta objetos de clase B, y la clase B define un operador de conversión de tipos cuyo objetivo de conversión es la clase A.

struct B;
struct A
{
    
    
	A() = default;
	A(const B&);	//把一个B转换为A
};

struct B{
    
    
operator A() const;	//也是把B转换为A
}

    A f(const A& a) {
    
    
        return a;
    }

B b;
A a = f(b);	//二义性错误,含义是 f(B::operator A()) 还是f(A::A(const B&)) ???

Si realmente desea ejecutar la llamada anterior, la llamada que debe mostrarse:

A a1 = f(b.operator A());
A a2 = f(A(b));

1.2 La clase define múltiples reglas de conversión de tipos, y los tipos involucrados en estas conversiones pueden vincularse ellos mismos mediante otras conversiones de tipos.

Conversiones de varios tipos marcadas como tipos integrados

 struct A{
    
    
	//最好不要创建两个转换源都是算术类型的类型转换
	A(int  = 0);
	A(double);
	//最好不要创建两个转换对象都是算术类型的类型转换
	operator int() const;
	operator double() const;
};

void f2(long double);
A a;
f2(a); //二义性错误,含义是 f(A::operator int()),还是f(A::operator double())

long lg;
A a2(lg);	//二义性错误,含义是A::A(int) 还是 A::A(double)

La conversión anterior provocará ambigüedad porque no existe la mejor coincidencia.

short s = 42;
A a3(s); //使用 A::A(int),因为short转换成int由于short转换成double

2. Principios de diseño

  • No defina el mismo tipo de conversión para dos clases y no defina dos o más fuentes de conversión u objetivos de conversión en una clase que sean conversiones de tipos aritméticos.
  • Si la clase contiene una o más conversiones de tipos, debe asegurarse de que solo haya un método de conversión entre el tipo de clase y el tipo de destino; de lo contrario, puede haber ambigüedad. Ej. El ejemplo más típico son los operadores aritméticos.
  • Cuando usamos dos conversiones de tipo definido por el usuario, si hay una conversión de tipo estándar antes o después de la función de conversión, la conversión de tipo estándar determinará cuál es la mejor coincidencia
  • Además de la conversión explícita al tipo bool, la definición de funciones de conversión de tipo debe evitarse y los constructores no explícitos "obviamente correctos" deben restringirse tanto como sea posible.

3. Funciones sobrecargadas y constructores de conversión

struct C
{
    
    
	C(int);
};
struct D
{
    
    
	D(int);
};

void manip(const C&);
void manip(const D&);
manip(10);	//二义性错误,含义是manip(C(10))还是manip(D(10))

manip(C(10));	//正确,显示的指明调用
  • Si necesita un constructor o una conversión de tipo forzada para cambiar el tipo de argumento al llamar a una función sobrecargada, esto generalmente significa que el diseño del programa es insuficiente.

4. Funciones sobrecargadas y conversión de tipos definidos por el usuario

Al llamar a funciones sobrecargadas, si hay más de un tipo de conversión y son diferentes entre sí, la llamada es ambigua. Incluso si una llamada requiere una conversión de tipo estándar adicional y la otra llamada puede coincidir exactamente, el compilador mostrará un error.

struct E
{
    
    
	E(double){
    
    }
};
manip(10);	//二义性错误,含义是manip(C(10))还是manip(E(10)) 

[Cita]

[1] Código classTypeExchange.h

Supongo que te gusta

Origin blog.csdn.net/thefist11cc/article/details/114210208
Recomendado
Clasificación