Classe correta Modelagem usando C++ e const
Pergunta
Deixe-me de preferência que eu, principalmente, desenvolver em C# e C++ development o que eu tenho feito não aproveitar plenamente a linguagem C++.Agora estou tentando usar o idioma como ele foi concebido e eu estou puxando meu cabelo com declarações const argumentos passados.No passado, eu nunca usou ou cortado o meu caminho para fazê-los funcionar com o STL.
O meu entendimento de que gostaria de criar a função a seguir, quando eu quero usar o como leitura-somente em função de:
void foo(const MyClass* o);
Então aqui está o meu problema...primeiro código:
#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;
}
Em main (), o compilador g++ versão 4.7.2) hesita em doSomethingB:
doSomethingA(o->child());
com o erro:passando 'const ClassB' como 'isso' argumento de " ClassA* ClassB::criança()' descarta qualificadores [-fpermissive]
Agora eu estou passando minhas aulas para funções como ponteiros.Estou pensando em sempre usando ponteiros, porque eu tenho um problema com a referência/opções de ponteiro.Eu estou escolhendo uma, ponteiros, e furar com ele.Assim doSomethingA e doSomethingB eu quero que seja constante para dizer o programador de que a sua classe não está sendo alterada.Mas eu só quero uma versão de criança() o que eu quero utilizar, por vezes, como "somente leitura" e, outras vezes, permitir que o usuário altere os dados no objeto filho (não é o melhor método, admito isso, mas há alguns casos de uso onde eu preciso disso).Eu até tentei:
doSomethingA(const_cast<const ClassA*>(o->child()));
Mas que não funcionou.
No passado, tirei o constante de declarações de funções para fazer algo parecido com este trabalho, mas agora eu quero adequado para c++.Ajuda por favor.
Solução
Você está tentando acessar um não-const função contra um objeto const.Você precisa fazer com que a função const
:
const ClassA* child() const { return &m_child; }
Você também pode fornecer uma constante e não-const versão:
ClassA* child() { return &m_child; }
const ClassA* child() const { return &m_child; }
Desta forma, você pode chamar de não-const métodos ClassA
quando você tem um não-objeto const.
Outras dicas
tente
ClassA* child() const { return &m_child; }
ou
const ClassA* child() const { return &m_child; }
para manter a constante de correção
Além disso, você não precisa usar ponteiros contanto que você não planeja passar nullptr.Assim, você pode fazer o seguinte:
void doSomethingB(const ClassB& o);
// in class ClassB
const ClassA& child() const { return m_child; }
ClassA& child() { return m_child; }
Referências ainda alow polimórficos coisas da mesma forma como ponteiros.