Pregunta

Permítanme preferir que desarrollo principalmente en C# y que el desarrollo de C++ que he realizado no aprovechó completamente el lenguaje C++.Ahora estoy tratando de usar el lenguaje como estaba previsto y me estoy arrancando los pelos con declaraciones constantes en argumentos pasados.En el pasado nunca los usé ni los pirateé para que funcionaran con STL.

Tengo entendido que crearía la siguiente función cuando quiera usar o como solo lectura en la función:

void foo(const MyClass* o);

Así que aquí está mi problema... código primero:

#include <iostream>
#include <string>

using namespace std;

///////////////////////////////////////////////////////////
// Classes are defined in the one file for an easy post.

///////////////////////////////////////////////////////////

class ClassA {
private: // member variables
    string m_name;

public: // constructors
    ClassA(const string& name = "") : m_name{name} {}
    virtual ~ClassA() { }

public: // accessors
    const string& name() const { return m_name; }
    void setName(const string& value) { m_name = value; }   
};

class ClassB {
private: // member variables
    string m_name;
    ClassA m_child;

public: // constructors
    ClassB(const string& name = "") : m_name{name} {}
    virtual ~ClassB() { }

public: // accessors
    const string& name() const { return m_name; }
    void setName(const string& value) { m_name = value; }

    ClassA* child() { return &m_child; }
    void setChild(const ClassA* value) { m_child = *value; }
};

///////////////////////////////////////////////////////////
// Protoptypes are not used to save space for the post.

void doSomethingA(const ClassA* o) {
   cout << "name = " << o->name() << endl << endl;
}

void doSomethingB(const ClassB* o) {
   cout << "name = " << o->name() << endl << endl;
   doSomethingA(o->child());
}

///////////////////////////////////////////////////////////

int main(int argc, char** argv) {
    ClassA a { "My Class A" };
    ClassB b { "My Class B" };


    b.setChild(&a);
    b.child()->setName("My New Name");
    doSomethingB(&b);
    return 0;
}

En main() el compilador (g++ versión 4.7.2) se resiste a hacerAlgoB:

doSomethingA(o->child());

con error:pasar 'const ClassB' como 'este' argumento de 'ClassA* ClassB::child()' descarta calificadores [-fpermissive]

Ahora estoy pasando mis clases a funciones como punteros.Planeo usar siempre punteros porque tengo un problema con las opciones de referencia/puntero.Elijo uno, sugerencias y me quedo con él.Entonces doSomethingA y doSomethingB quiero que sea constante para decirle al programador que su clase no está siendo alterada.Pero solo quiero una versión de child() que quiero usar a veces como "solo lectura" y otras veces permitir al usuario cambiar los datos dentro del objeto secundario (no es el mejor método, lo admito, pero hay algunos usos). casos en los que necesito esto).Incluso lo intenté:

doSomethingA(const_cast<const ClassA*>(o->child()));

Pero eso no funcionó.

En el pasado eliminé las declaraciones constantes en las funciones para que algo como esto funcione, pero ahora quiero usar C++ adecuado.Ayuda por favor.

¿Fue útil?

Solución

Estás intentando acceder a una función no constante contra un objeto constante.Necesitas hacer la función. const :

const ClassA* child() const { return &m_child; }

También puede proporcionar una versión constante y no constante:

ClassA* child() { return &m_child; }
const ClassA* child() const { return &m_child; }

De esta manera puedes llamar a métodos no constantes en ClassA cuando tienes un objeto no constante.

Otros consejos

try

ClassA* child() const { return &m_child; }

o

const ClassA* child() const { return &m_child; }

para mantener la corrección del Const

Además, no necesita usar los punteros siempre que no planee pasar a NullPtr.Para que pueda hacer lo siguiente:

void doSomethingB(const ClassB& o);

// in class ClassB
const ClassA& child() const { return m_child; }
ClassA& child() { return m_child; }

Las referencias siguen siendo las cosas polimórficas de la misma manera que los punteros.

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