Posso trasmettere una class derivata ad una class base privata, usando il cast in stile C?

Posso farlo?

class A { ... }; class B : private A { const A &foo() const { return *((const A *)this); } }; 

Posso prendere una sottoclass che eredita privatamente da una class base e trasmetterla a una versione pubblica della sua class base? Posso farlo senza avere metodi virtuali?

La mia ipotesi è sì, ma volevo assicurarmi che fosse sicuro / portatile.

Sì, puoi: §5.4 / 7 dello standard:

… le seguenti operazioni static_cast e reinterpret_cast (opzionalmente seguite da un’operazione const_cast) possono essere eseguite utilizzando la notazione cast della conversione del tipo esplicito, anche se il tipo di class base non è accessibile:

un puntatore a un object di tipo class derivata o un lvalue di tipo di class derivata può essere convertito esplicitamente in un puntatore o in un riferimento a un tipo di class base non ambigua, rispettivamente;

Ma provate a non sconfiggere lo scopo dell’eredità privata.

Sì, è esplicitamente permesso. Alexandrescu lo utilizza estensivamente in Modern C ++ Design per il suo approccio alla progettazione basata su policy:

 template  class foo : Policy { public: void do_something() { Policy & p = *this; p.do_something(); } }; 

Quindi, mentre i casi d’uso possono essere limitati, ce ne sono alcuni là fuori.

Base sul titolo della domanda, la risposta dipende. Ma per il tuo caso nel codice sorgente, la risposta è sì.

Ci sono due fattori che influenzeranno la risposta:

  1. Se usi il cast di stile C, lo farà, perché il cast chiamerà il cast reinterpert se non è disponibile alcuna conversione. Puoi lanciare qualsiasi tipo di puntatore al tipo di puntatore di destinazione. Ma se c’è MI, il risultato potrebbe essere errato per la maggior parte dell’implementazione del linguaggio C ++.

  2. Se si esegue il cast (senza cast di stile C) all’interno della funzione memeber, il risponditore sarà sì, perché la class base è accessibile all’interno della funzione membro. Se l’espressione si trova nella posizione in cui la class base è inaccessibile, verrà visualizzato un errore di compilazione.

Ci sono più dettagli sulla conversione standard nello standard C ++

 A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class (Clause 10) of D. If B is an inaccessible (Clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formsd. The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type. 

Modifica 2: rendere la risposta più dettagliata.