arestides Posted January 9, 2010 at 08:50 PM Report Share #305053 Posted January 9, 2010 at 08:50 PM Não quero abuzar da vossa paciencia, mas estou com problemas para encontrar erros e soluções para estes em mais alguns exames. Se alguem me poder ajudar agradecia imenso. Então ca vai: 1- class Base{ public: int operator == (const char *); //... }; class Derived : public Base { public: int operator == (int); //... }; void main(){ Derived d1; if (d1 == 1024 && d1 == "ana") //... return d1; } 2- class Word { public: Word(char *); //... private: string namez; int occurs; }; int main() { //... Word noun ("book"); Word verb = noun; //... return 0; } 3- class target_class{ friend class friend_class; private: double salary; int rating; }; target_class classA; int main () { char *p = (char *) &classA; classA.rating=5; int *pd = (int*) (p+sizeof(double)); *pd = 5; return 0; } Aguardo sugestões. O meu, muito obrigado pela ajuda que me tem dado. 👍 Link to comment Share on other sites More sharing options...
mogers Posted January 11, 2010 at 10:18 AM Report Share #305401 Posted January 11, 2010 at 10:18 AM 1) Para além do "return d1" na função main que foi definida como void, isto tem um comportamento diferente do que eu esperava (tive de andar a experimentar o código, imagino que já o tenhas feito também). O operador == da superclasse não é herdado, mas eu não sei exactamente porquê. Parece-me que devido a existir um operador == definido em Derived, todos os operadores == da superclasse são descartados. Não tenho nenhum livro à mão, convinha verificares qual é o detalhe da herança em causa. 2) O construtor devia ter um parâmetro com o tipo "const char *" para receber uma string literal. 3) Aqui está a tentar-se quebrar o encapsulamento da classe usando conhecimentos sobre a sua implementação. "classA.rating=5;" é impedido por ser um acesso a um membro privado da classe. Mas a alteração do rating através do apontador é conseguida com sucesso (já fiz algo semelhante num projecto em C). Contudo, para além de não se dever quebrar o encapsulamento das classes, penso que a forma como os dados de um objecto são armazenados deve ser dependente da implementação do compilador e isto é outro motivo para evitar este tipo de truques. "What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação. Link to comment Share on other sites More sharing options...
Metaluim Posted January 11, 2010 at 02:51 PM Report Share #305441 Posted January 11, 2010 at 02:51 PM Como o mogers disse, isto é bastanto perigoso: int *pd = (int*) (p+sizeof(double)); Nada te garante que a classe em memória não tem (porque muitas vezes tem) intervalos de células vazios, "padding". Daí, nunca podes assumir que os membros estão seguidos em memória pelo espaço que ocupam. Link to comment Share on other sites More sharing options...
arestides Posted January 11, 2010 at 04:41 PM Author Report Share #305457 Posted January 11, 2010 at 04:41 PM Boas, mais uma vez muito obrigado ao mogers e ao metaluim pela ajuda. 1-Pelo que entendi o problema é a sobrecarga do operator ==, pois dois operadores com parametros diferentes tem a mesma designação. A solução pode ser declarar na classe derivada o operator == como fiend. Ex: friend int operator == (int); 2- Se declarar no construtor da classe Word: "Word (const char*);" o copy constructor default "Word verb=noun;" já copia o conteudo do objecto sem havel alterações....era esse o prblema?! 3- Nesta a violação do encapsulamento está em "*pd=5" ?como é k este ponteiro consegue aceder ao membro privado? Esta é a k esta a fazer-me mais confusão...Como deve ser reservada a memoria correctamente, com "int * pd =new int", ou o problema é o local ond ela é reservada? Desculpem la a minha "ignorancia" na materia... 😁 Link to comment Share on other sites More sharing options...
mogers Posted January 11, 2010 at 06:31 PM Report Share #305481 Posted January 11, 2010 at 06:31 PM 1) Em que é que o friend ajuda? 2) Eu acho que o construtor por cópia não afecta nada visto que os atributos da classe são uma string e um inteiro. Uma string literal é uma coisa imutavel. Assim, para a usares como parametro, este tem de ser constante. 3) Isso era o que o Metalium se referia no seu post noutro tópico (teu) http://en.wikipedia.org/wiki/Diamond_problem o primeiro parágrafo diz tudo, mas C++, com alguns truques também podes aceder a membros privados (com apontadores) e também tens a keyword friend, que, quando uma classe Foo é "amiga" de uma classe Bar, a Foo tem acesso a toda a interface da Bar (privates incluídos). A linguagem protege os acessos directos (como classA.rating dá erro), mas a memória não é protegida (em c++ não me parece uma coisa viável, penso que teria de ser feito em runtime e a eficiência deteriorava-se). Por isso, estes truques com apontadores podem tentar aceder aos dados privados. "What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação. Link to comment Share on other sites More sharing options...
arestides Posted January 11, 2010 at 08:18 PM Author Report Share #305503 Posted January 11, 2010 at 08:18 PM ok...ja entendi, obrigadão. A função friend tem os mesmos previlegios de uma função membro da classe, mas da acesso aos campos privados de outros objectos, é utilizada mesmo para overload de operadores. Link to comment Share on other sites More sharing options...
mogers Posted January 11, 2010 at 08:42 PM Report Share #305508 Posted January 11, 2010 at 08:42 PM A função friend tem os mesmos previlegios de uma função membro da classe, mas da acesso aos campos privados de outros objectos, é utilizada mesmo para overload de operadores. Eu sei, mas não entendo qual é a sua utilidade neste caso. O problema não me parece relacionado com o encapsulamento. Creio que o problema é que o operador == definido na superclasse não foi herdado (a minha suposição foi por haver um operador == definido na subclasse e esta ignorar os == definidos na superclasse), mas não consegui obter nenhuma referência decente na net sobre isto e não tenho nenhum livro à disposição. Talvez alguém saiba... Metalium, fazes ideia? PS: estou a achar estas perguntas bastante úteis para se pensar em pormenores da linguagem. Já vi que em muitas entrevistas de emprego perguntam coisas deste género. Podes disponibilizar os enunciados de exames que tens? Os que tive não costumavam ter perguntas deste género. "What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação. Link to comment Share on other sites More sharing options...
arestides Posted January 11, 2010 at 10:55 PM Author Report Share #305553 Posted January 11, 2010 at 10:55 PM Claro, vou colocar o resto das perguntas praticas k tenho no proximo post. Link to comment Share on other sites More sharing options...
Metaluim Posted January 12, 2010 at 12:28 AM Report Share #305568 Posted January 12, 2010 at 12:28 AM O friend é um keyword que não costumo usar (acho que só usei uma vez, e não foi da maneira que é suposto ser usado). Eu fui testar isso dos operadores, e com este código que fiz, não houve problema: #include <iostream> using namespace std; class Foo { private: int m_int; public: Foo (const int &intNum); bool operator == (const int &); Foo (){}; const Foo operator = (const Foo &){}; ~Foo (){}; }; Foo::Foo (const int &intNum) : m_int(intNum) {}; bool Foo::operator == (const int &comp) { return (m_int == comp) ? true : false; } class Bar : public Foo { private: int m_megaInt; public: Bar (const int &megaInt); bool operator == (const char *); }; Bar::Bar (const int &megaInt) : m_megaInt(megaInt) {}; bool Bar::operator == (const char *str) { return (str) ? true : false; } int main () { Foo base(666); Bar derived(69); cout << ((base == 666) ? "true" : "false") << endl; cout << ((derived == NULL) ? "true" : "false") << endl; system("PAUSE"); return 0; } compilado com o g++, pois tinha-me esquecido disso, mas funcionou na mesma. Link to comment Share on other sites More sharing options...
mogers Posted January 12, 2010 at 12:32 AM Report Share #305569 Posted January 12, 2010 at 12:32 AM Mas ambos == recebem um parâmetro do mesmo tipo. Naquele código da pergunta eram 2 operadores == com parametros diferentes e pelo que observei, o == definido na superclasse é descartado (e num teste rápido pareceu-me que acontece o mesmo com funções normais). edit: ou seja, o comparador == que na superclasse comparava com um const char *, deixa de ser utilizado e a comparação obj == "coiso" dá erro (enquanto a comparação obj == 10 funciona, tendo o operador == para ints na subclasse). "What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação. Link to comment Share on other sites More sharing options...
TheDark Posted January 12, 2010 at 02:13 AM Report Share #305606 Posted January 12, 2010 at 02:13 AM Não é descartado, tanto quanto percebi (também não tinha noção disso) é escondido. É possível aceder-lhe de duas maneiras: ou utilizando um apontador para a classe base Derived d1; Base *pb = &d1; if (d1 == 1024 && *pb == "ana") //... ou utilizando uma referência explícita ao tipo Base Derived d1; if (d1 == 1024 && d1.Base::operator==("ana")) //... Ainda não compreendi as razões para isto acontecer, mas devem existir :👍 De qualquer forma, isto viola um pouco a abstracção... o programador tem que conhecer minimamente o tipo Base. Desaparecido. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now