Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

arestides

Novos problemas no código

Mensagens Recomendadas

arestides

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. :thumbsup:

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mogers

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Metaluim

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
arestides

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... :cheesygrin:

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mogers

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
arestides

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mogers

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Metaluim

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mogers

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
TheDark

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 ::thumbsup:

De qualquer forma, isto viola um pouco a abstracção... o programador tem que conhecer minimamente o tipo Base.


Desaparecido.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.