Jump to content

Novos problemas no código


arestides
 Share

Recommended Posts

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

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

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

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

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

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

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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.