tengo una clase (vamos a llamarlo base
por el momento) que tiene una interfaz protegida, incluyendo constructores protegidas etc. Algunas funciones de base
devolver una instancia de base
por valor:tema visibilidad para constructor de copia de clase base
class base {
protected:
base() {}
base (base const &other) {} // line 6
base foo() {
base ret;
return ret;
}
};
Estas funciones están envueltos en las clases derivadas para devolver el tipo derivado de este modo:
class derived : public base {
private:
derived(base const &b) : base(b) {}
public:
derived() : base() {}
derived foo() {
derived d(base::foo()); // line 21
return d;
}
};
para facilitar la conversión del tipo base
retorno en un derived
tipo de devolución, proporciono un constructor privado en derived
que maneja esto.
la compilación de este en Centos 5.8 con gcc 4.1.2 produce el siguiente error:
test.cpp: In member function ‘derived derived::foo()’:
test.cpp:6: error: ‘base::base(const base&)’ is protected
test.cpp:21: error: within this context
con GCC 4.6.1 y 2.9 sonido metálico en Linux Mint 12, el código se compila archivos, incluso con -Wall -Wextra
, además de una advertencia unused parameter
para el constructor de copia base
.
Creo que esto podría ser un error del compilador en gcc 4.1.2, pero no he podido encontrar nada en la red. ¿Alguien ha visto esto antes?
No puedo actualizar el compilador sin mucho dolor. ¿Hay alguna solución alternativa aparte de hacer público el constructor de copia de la clase base?
EDITAR I añadió base b;
antes de la línea 21 en derived::foo()
. En ese caso, gcc 4.6.1 y gcc 4.1.2 se quejan de que el ctor predeterminado de base
está protegido, clang 2.9 compila sin previo aviso. Esto es lo que David Rodríguez - dribeas dijo en su comentario - no se puede llamar al ctor por defecto en una instancia diferente de base
.
EDIT 2 El párrafo estándar que parece aplicarse aquí es 11.5 [class.protected]. gcc 4.1.2 parece ser correcto al rechazar mi código como incorrecto y me pregunto por qué gcc 4.6.1 y clang lo permiten. Ver mi propia respuesta para una solución preliminar.
Dado que MarkB ha eliminado su respuesta, publicaré aquí el punto principal: 'protected' no da a los tipos derivados acceso a esos miembros en * cualquier * instancia de la base tipo. Solo puede acceder a los miembros protegidos de su propio tipo derivado. Es decir.'derived :: foo()' solo puede acceder a los miembros protegidos de 'base' de' this' o de cualquier otro objeto 'derived' (incluidos los objetos cuyo tipo completo se deriva de' derived') –
Sí, he leído sobre eso también (incluso lo busqué en el estándar), y esta también fue mi primera idea, pero me pregunto por qué tanto gcc 4.6.1 como clang 2.9. compilar esto sin problemas. – arne
+1 @ DavidRodríguez-dribeas ojo abierto. He estado bajo la impresión equivocada todo este tiempo. No solo eso, estaba ** seguro ** de exactamente lo contrario. –