operadores - punteros c++
¿Cómo funcionan los operadores de conversión en C++? (7)
Algunas situaciones aleatorias donde las funciones de conversión se usan y no se usan siguen.
En primer lugar, tenga en cuenta que las funciones de conversión nunca se utilizan para convertir al mismo tipo de clase o a un tipo de clase base.
Conversión durante el paso de la discusión
La conversión durante el paso del argumento usará las reglas para la inicialización de la copia. Estas reglas solo consideran cualquier función de conversión, sin tener en cuenta si se convierte a una referencia o no.
struct B { };
struct A {
operator B() { return B(); }
};
void f(B);
int main() { f(A()); } // called!
La aprobación de argumentos es solo un contexto de inicialización de copia. Otra es la forma "pura" que utiliza la sintaxis de inicialización de copia
B b = A(); // called!
Conversión a referencia
En el operador condicional, la conversión a un tipo de referencia es posible, si el tipo convertido es un valor l.
struct B { };
struct A {
operator B&() { static B b; return b; }
};
int main() { B b; 0 ? b : A(); } // called!
Otra conversión a referencia es cuando vincula una referencia, directamente
struct B { };
struct A {
operator B&() { static B b; return b; }
};
B &b = A(); // called!
Conversión a indicadores de función
Puede tener una función de conversión a un puntero o referencia de función, y cuando se realiza una llamada, puede ser utilizada.
typedef void (*fPtr)(int);
void foo(int a);
struct test {
operator fPtr() { return foo; }
};
int main() {
test t; t(10); // called!
}
Esto puede llegar a ser bastante útil a veces.
Conversión a tipos no de clase
Las conversiones implícitas que ocurren siempre y en todas partes también pueden usar conversiones definidas por el usuario. Puede definir una función de conversión que devuelva un valor booleano
struct test {
operator bool() { return true; }
};
int main() {
test t;
if(t) { ... }
}
(La conversión a bool en este caso se puede hacer más segura mediante el modismo safe-bool , para prohibir las conversiones a otros tipos de entero.) Las conversiones se desencadenan en cualquier lugar donde un operador incorporado espera un determinado tipo. Las conversiones pueden entrar en el camino, sin embargo.
struct test {
void operator[](unsigned int) { }
operator char *() { static char c; return &c; }
};
int main() {
test t; t[0]; // ambiguous
}
// (t).operator[] (unsigned int) : member
// operator[](T *, std::ptrdiff_t) : built-in
La llamada puede ser ambigua, porque para el miembro, el segundo parámetro necesita una conversión, y para el operador integrado, el primero necesita una conversión definida por el usuario. Los otros dos parámetros coinciden perfectamente, respectivamente. La llamada puede ser no ambigua en algunos casos ( ptrdiff_t
necesita ser diferente de int
luego).
Plantilla de función de conversión
Las plantillas permiten algunas cosas agradables, pero es mejor tener mucho cuidado con ellas. Lo siguiente hace que un tipo sea convertible a cualquier tipo de puntero (los punteros de miembro no se ven como "tipos de puntero").
struct test {
template<typename T>
operator T*() { return 0; }
};
void *pv = test();
bool *pb = test();
Considera este simple ejemplo:
template <class Type>
class smartref {
public:
smartref() : data(new Type) { }
operator Type&(){ return *data; }
private:
Type* data;
};
class person {
public:
void think() { std::cout << "I am thinking"; }
};
int main() {
smartref<person> p;
p.think(); // why does not the compiler try substituting Type&?
}
¿Cómo funcionan los operadores de conversión en C ++? (es decir, ¿cuándo intenta el compilador sustituir el tipo definido después del operador de conversión?
Deberías hacer
((person)p).think();
El compilador no tiene la información para enviar automáticamente a la persona, por lo que necesita un casting explícito.
Si usaras algo como
person pers = p;
Luego, el compilador tiene información para transmitir implícitamente a la persona.
Puede tener "casting" a través de constructores:
class A
{
public:
A( int );
};
A a = 10; // Looks like a cast from int to A
Estos son algunos ejemplos breves. Casting (implícito, explícito, etc.) necesita más explicaciones. Puede encontrar detalles en libros serios de C ++ (consulte las preguntas sobre libros en C ++ sobre desbordamiento de pila para obtener buenos títulos, como este ).
El compilador intentará un molde (!) Definido por el usuario (operador de conversión o ctor implícito) si intenta utilizar un objeto (referencia) de tipo T
donde se requiere U
El .
operador, sin embargo, siempre intentará acceder a un miembro del objeto (referencia) en su lado izquierdo. Así es como está definido. Si desea algo más elegante, eso es lo que el operator->()
puede estar sobrecargado.
La conversión implícita (ya sea por operadores de conversión o constructores no explícitos) se produce al pasar parámetros a las funciones (incluidos los operadores sobrecargados y por defecto para las clases). Además de esto, hay algunas conversiones implícitas realizadas en tipos aritméticos (por lo que la adición de un char y un resultado largo en la adición de dos longs, con un resultado largo).
La conversión implícita no se aplica al objeto sobre el que se realiza una llamada a la función miembro: a los efectos de la conversión implícita, "esto" no es un parámetro de función.
Las conversiones no son mágicas. El hecho de que A tenga una conversión a B y B tenga un método foo no significa que a.foo () llamará a B :: foo ().
El compilador intenta usar una conversión en cuatro situaciones
- Expulsa explícitamente una variable a otro tipo
- Usted pasa la variable como argumento a una función que espera un tipo diferente en esa posición (los operadores cuentan como funciones aquí)
- Asignas la variable a una variable de un tipo diferente
- Utiliza la variable copy-construct o inicializa una variable de un tipo diferente
Hay tres tipos de conversiones, distintas de las relacionadas con la herencia
- Conversiones incorporadas (por ejemplo, int-to-double)
- Construcción implícita, donde la clase B define un constructor tomando un solo argumento de tipo A, y no lo marca con la palabra clave "explícita"
- Operadores de conversión definidos por el usuario, donde la clase A define un operador B (como en su ejemplo)
Cómo el compilador decide qué tipo de conversión usar y cuándo (especialmente cuando hay múltiples opciones) es bastante complicado, y haría un mal trabajo tratando de condensarlo en una respuesta en SO. La sección 12.3 del estándar de C ++ analiza la construcción implícita y los operadores de conversión definidos por el usuario.
(Puede haber algunas situaciones de conversión o métodos en los que no he pensado, así que coméntelos o edítelos si ve que falta algo)
Los "." el operador no se puede descargar en C ++. Y cada vez que diga xy, no se realizará ninguna conversión automáticamente en x.
// Tabla virtual Fuction (VFT)
#include <iostream>
using namespace std;
class smartref {
public:
virtual char think() { }//for Late bindig make virtual function if not make virtual function of char think() {} then become early binding and pointer call this class function
smartref() : data(new char) { }
operator char(){ return *data; }
private:
char* data;
};
class person:public smartref
{
public:
char think() { std::cout << "I am thinking"; }
};
int main() {
smartref *p;//make pointer of class
person o1;//make object of class
p=&o1;//store object address in pointer
p->think(); // Late Binding in class person
return 0;
}