Derivato getto * const a const Base *
-
08-10-2019 - |
Domanda
Modifica -. Mettere la questione in un contesto un po 'più
Data:
struct Base
{
...
};
struct Derived : public Base
{
...
};
class Alice
{
Alice(Base *const _a);
...
};
class Bob : public Alice
{
Bob(Derived *const _a);
...
};
Quando provo ad implementare
Bob::Bob(Derived *const _d) : Alice(static_cast<Base*const>(_d)) { }
non funziona. un const_cast
non ha senso per me come io non voglio cambiare la costanza, e non sto cambiando quello che sto indicando, quindi perché poi non g ++ dimmi
invalid static_cast from type ‘Derived* const’ to type ‘Base* const’
? Se lascio il cast, si dice
no matching function for call to ‘Alice::Alice(Derived* const)’
Se qualcuno potesse far luce su questo sarebbe molto apprezzato.
Soluzione
Il problema era che Derivato era un tipo incompleto, vale a dire in avanti dichiarato. Ho paura che ho dando a tutti un momento difficile :( La risposta spuntato quando Kiril Kirow proposto di utilizzare una dinamica-cast, su cui g ++ sputato fuori questo errore un po 'più utile:
error: cannot dynamic_cast ‘_d’ (of type ‘struct Derived* const’) to type ‘struct Base* const’ (source is a pointer to incomplete type)
Purtroppo, ho avuto in avanti dichiarato Derivato, ma non avevo capito che era rilevante, ed è stato nascosto diverse intestazioni più in basso, che avrebbero dovuto mi distacco troppo codice qui. Siamo spiacenti tutti, ma spero che questo almeno aiuta a qualcun altro più tardi.
Altri suggerimenti
Non c'è bisogno di alcuna fusione a tutti. Hai puntatori const, non puntatori a oggetti const. Ed è legale per assegnare l'indirizzo di un oggetto derivato a un puntatore-a-base senza un cast.
Ho una teoria. Che cosa succede se durante la derivazione si era accidentalmente dimenticato di specificare che la derivazione è pubblico? In questo caso sarebbe privato per impostazione predefinita e la conversione di cui sopra sarebbe inaccessibile.
Sei sicuro che hai scritto
class Derived : ***public*** Base {...}
?
O forse hai dimenticato pubblico? Solo una teoria ...
Questa compila perfettamente su g ++ 4.4.3, senza nemmeno gli avvertimenti:
#include <iostream>
struct Base
{
Base()
{
}
};
struct Derived : public Base
{
Derived() {}
};
class Alice
{
public:
Alice( Base *const _a )
{
std::cout << "Alice::Alice" << std::endl;
}
};
class Bob : public Alice
{
public:
Bob(Derived *const _a)
: Alice( static_cast< Base * const >( _a ) )
{
std::cout << "Bob::Bob" << std::endl;
}
};
int main()
{
Derived* pDer = new Derived();
Bob b( pDer );
return 0;
}
Hai tipi non correlati Alice
e Base
. Modificare il costruttore Alice
di prendere una Base*
.
A proposito, ho sospettato di avere i posizionamenti const
sbagliata.
Saluti e hth.,
L'unico problema qui è che Alice::Alice
è privata in Alice
. Bob
non ha accesso a Alice::Alice
.
Non ci sono problemi di sorta con il cast. In realtà, non è necessario un static_cast
per esso. Esso dovrebbe essere convertito in modo implicito.
Il static_cast
attualmente si dispone è valido, tranne che per un qualificatore const
ridondante nel tipo di destinazione. Che const
fa non semplicemente non ha senso, ma non è un errore.
Perché il compilatore emette questi messaggi di errore bizzarri, non mi è chiaro. Ho il sospetto che il codice che hai postato è falso.
Mentre io non sono sicuro (troppo poco contesto) Penso che si potrebbe avere significato const Base * e Derivato const * .
const Base * è un puntatore ad oggetto base costante. Base * const è un puntatore costante oggetto di base modificabili.