Pregunta

Cómo implementar fundición a una clase de base privada en C ++? No quiero usar hacks, tales como la adición de un amigo, etc. La definición de operador de fundición pública no funciona.

EDIT:

Por ejemplo tengo:

class A {
//base class
}

class AX : private A {
//a child
}

class AY : private A {
//another specialized child
}

class B {
//base class
void do (A a) {//do
    }
}

class BX : private B {
//a child
void do (AX a) {
     B::do( static_cast <A> (a) );
    }
}

class BY : private B {
//another specialized child
void do (AY a) {
    B::do( static_cast <A> (a) );
    }
}

Edit2

¿Por qué hago esto?

Supongamos que tengo para definir una propiedad que es bastante pesado y pueden ser de varios tipos similares (como VelocityX VelocityY etc). Entonces quiero ser capaz de tener clases que pueden tener cualquier conjunto de estas propiedades. Si quiero procesar estas propiedades, es obvio, que en lugar de ellos había lanzado a su tipo de base que añadir una implementación para cada variación. No consumo patrimonio público porque es mejor para convertir explícitamente cuando sea necesario, que tener la interfaz privada implícitamente visible. No es un problema real, pero me gustaría tener una solución:)

¿Fue útil?

Solución

Si la definición de un operador de fundición pública no funciona, se puede tratar con una función regular:

class D: private B {
    public:
        B& asB() { return static_cast<B&>(*this); }
};
...
D d;
d.asB().methodInB();
...

De todos modos, ¿cuál es el punto? Si privada de D, entonces se supone que no se deriva B utilizar un D como B desde el exterior.

Otros consejos

Sólo puede utilizar una conversión de estilo C. No hay necesidad de "hacks" o "implementaciones". Envolviéndolo en una función explícita sirve a los "moldes al estilo C son malas" personas

template<typename Targ, typename Src>
typename boost::enable_if<boost::is_base_of<Targ, Src>, Targ>::type &
private_cast(Src &src) { return (Targ&)src; }

Para que el seguro fundido, es necesario asegurarse de que Targ es en realidad una base privada o pública. Esto se hace mediante boost::is_base_of.


Por supuesto, se debe preferir funciones miembro en la respectiva clase derivada que devuelven el puntero de base, en vez de hacer un reparto tan. .


La definición de operador de fundición público no funciona.

Eso no tiene sentido para mí ... ¿Por qué hacer la clase de base privada, en ese caso? Sólo hacerlo público. La razón de sus funciones de conversión no hacen el trabajo se debe a que la norma requiere que las conversiones implícitas nunca tienen en cuenta las funciones de conversión a una clase base, la propia clase o void.

Tengo un caso de uso para esto; Estoy heredando de una clase base grande y volátil que es la adición de funciones todo el tiempo y casi nunca es la función de la clase base va a funcionar correctamente en mi subclase, así que hereda de forma privada.

Creo que es más simple sólo para hacer una función que retorna la base de clase. A continuación Puedo también un programa totalmente corregido; Por favor, tratar de compilar el código antes de enviar una pregunta, ya que el uso de identificadores como "hacer" como nombres de función es probable que cada compilador infeliz .. :-(: - (

class A {
  //base class                                                                                                                                                          
};

class AX : private A {
  //a child                                                                                                                                                             
 public:
  A *ToA() { return this; }
};

class AY : private A {
  //another specialized child                                                                                                                                           
 public:
  A *ToA() { return this; }
};

class B {
  //base class                                                                                                                                                          
 protected:
  void do_it (A a) {};
};

class BX : private B {
  //a child                                                                                                                                                             
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

class BY : private B {
  //another specialized child                                                                                                                                           
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top