Jump to content

C++ com Eclipse CDT no Linux Ubuntu.


Recommended Posts

Posted (edited)

Boas,

No âmbito de um trabalho para a faculdade estou a utilizar, por razões várias, o Eclipse CDT versão 1.4.2 no Linux Ubuntu 12.04 LTS.

Sempre que crio um novo projeto c++ no Eclipse, tenho bastante dificuldade em que o Eclipse reconheça as bibliotecas standard do c++. Por exemplo na classe (muito simples) abaixo o Eclipse apresenta-me sempre a mensagem "Type 'ostream' could not be resolved", apesar de na definição estar o #include <iostream> e usar o namespace std.

#ifndef ROBOT_H_
#define ROBOT_H_

#include <iostream>

using namespace std;

class Robot
{
private:
int chave;
float capMaxCarga;
float qtdMatPrimDisp;
int posicao;

public:
Robot();
Robot(int c, float cap, float qtd, int pos);
Robot (const Robot &r);
~Robot();

int getChave() const;
void setChave(int c);
float getcapMaxCarga() const;
void setCapMaxCarga(float cmc);
float getQtdMatPrimDisp() const;
void setQtdMatPrimDisp(float qmpd);
int getPosicao() const;
void setPosicao(int pos);

bool operator == (const Robot &r);
bool operator > (const Robot &r);
const Robot& operator = (const Robot &r);
void escreve(ostream &out) const;
};

#endif /* ROBOT_H_ */

No entanto a classe é compilada sem nenhum problema. Tentei fazer o rebuild do index do projeto, se fizer F3 no <iostream> tenho acesso à sua estrutura, logo não é um problema de dependências mas a mensagem continua a aparecer e é muito aborrecido ter um ficheiro cheio de linhas sublinhadas e sinais vermelhos.

Penso que se trata de um bug do Eclipse mas não encontrei nenhuma solução.

Alguém já teve este problema? Se sim como o resolveram?

Obrigado desde já pela ajuda.

Edited by Baderous
geshi
Posted (edited)

o problema é tanto do eclipse como de todos os outros cimpiladores : não tem problema nenhum

os objectos/funcionalidades ds STL estão definidos dentro do namesapce std

por isso ou declaras desta maneira:

std::ostream

ou dizes que estas a usar as funcionalidades do namespace pretendido

#include <iostreamh>
using namespace std;

ps : já agora, não podes ter uma instância do ostream por ser uma classe genérica, logo só podes usar como ponteiro

Edited by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
  • 1 month later...
Posted

Tas a criar o construtor de copia e reimplementar o operador "=" sem necesidade, o GCC implementa-o- implicitamente.

Tambem reparei que tas a usar a versao 1.4.2 do CDT ao que a versao mais atual e 8.x.x

Victarion seized the dusky woman by the wrist and pulled her to him.

Victarion - She will do it. Go pray to your red god. Light your fire, and tell me what you see.

Moqorro's dark eyes seemed to shine.

Moqorro - I see dragons.

Posted

Tas a criar o construtor de copia e reimplementar o operador "=" sem necesidade, o GCC implementa-o- implicitamente.

testa o seguinte código :

#include <stdio.h>
#include <string.h>

class Test
{
protected:
int * list;

public:
Test()
{
	list = new int[10];
	printf("allocated : %p\n", list);
}

Test(const Test& t)
{
	list = new int[10];
	printf("allocated : %p\n", list);
	memcpy(list, t.list, sizeof(int)*10);
}

virtual ~Test()
{
	delete [] list;
	printf("freed : %p\n", list);
}
};

int main()
{
Test t1;
Test t2 = t1;
Test t3;

t3 = t1;

return 0;
}
  • Vote 1
IRC : sim, é algo que ainda existe >> #p@p
Posted

testa o seguinte código :

Fui compilar (com as flags -W -Wall e -Wextra) a tua listagem e correu tudo bem, e fiz o overload do operador = na clase Test e percebi o seguinte:

int main()
{
 Test t1;
 Tes t2 = t1; // chama o construtor de copia (pensa que chamava o operador =)
 t1 = t2; // aqui sim chama o operador = overloaded.
 return 0;
}

🙂 obrigado pela tua listagem.

Victarion seized the dusky woman by the wrist and pulled her to him.

Victarion - She will do it. Go pray to your red god. Light your fire, and tell me what you see.

Moqorro's dark eyes seemed to shine.

Moqorro - I see dragons.

Posted

Por caso nao vi porque estava a tentar entender as peculiaridades do contrutor de copia e o operador "=" implicito que o GCC gera e tinha a linha

t3 = t1;

comentada, ja vi a memory leak que querias mostrar me. Para lem disso existe ainda mais um problema com a listagem que me apresentaste (esta deixaste para eu encontrar sozinho 🙂 ), existe um double free do atributo list.

Considerando o seguinte exemplo:

// Acho que o GCC esta a fazer isto implicitamente, o que faz com que o atributo
// list da nova referencia aponta para um mesmo a endereco em memoria onde a
// referencia Test recebida coma parametro aponta, e quanda t3 sair do escopo o
// destrutor ira fazer um delete a um endereco que ja tinha sido libertado anteriormente.
Test& operator = (const Test& test)
{
   // o gcc devia fazer isto :
   delete [] this->list; // para impedir o leak the sizeof(int) * 10 bytes

   // mas na verdade faz algo como isto :
   this->list = test.list; // coloca dois objectos a apontarem para um mesmo endereco

   // uma das implementacoes corretas devia ser algo como :
   delete [] this->list;
   this->list = new int[10];
   memcpy(this->list, test.list, sizeof(int) * 10);

   return *this;
}

@HappyHippyHippo era isto que pretendias que eu visse?

Victarion seized the dusky woman by the wrist and pulled her to him.

Victarion - She will do it. Go pray to your red god. Light your fire, and tell me what you see.

Moqorro's dark eyes seemed to shine.

Moqorro - I see dragons.

Posted (edited)

sim

o exemplo era para apresentar os problemas de deixar o compilador tratar esse tipo de coisas.

este tipo de problemas é mutio relevante quando a classe deverá gerir memória e/ou gerir acessos de recursos do sistema.

por outro lado, a definição do operador "=" também tem os seus problemas, nomeadamente o problema de self-assignment

ps : para um exemplo claro de self-assigning vou usar o teu código do operador=

Test& operator = (const Test& test)
{
   // lembrate que é um self-assign
   // this == &test !!!!

   delete [] this->list; // pufff, lá foi a memória de test->list
   this->list = new int[10];
   memcpy(this->list, test.list, sizeof(int) * 10);

   return *this;
}

int main()
{
 Test test;

 test = test; // não existe problema nenhum em fazer isto !!!

 return 0;
}
Edited by HappyHippyHippo
  • Vote 1
IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

Ola HappyHippyHippo quando vi o teu ultimo post pesquisei sobre isso e encontrei um post que falava sobre isso e um dos comentarios nesse post foi para ler o livro Effective C++ (Scott Meyer), e assim fiz ja li 18 items que ele cubre sobre os Gotcha's do C++, recomendo a leitura daquele livro (se ainda nao o leste).

Podiamos protefer do self-assignment da seguinte forma:

Test& operator = (const Test& test)
{
// lembrate que é um self-assign
// this == &test !!!!
// se for um self-assignment termina a execucao
if (this == &test) return *this;
delete [] this->list; // pufff, lá foi a memória de test->list
this->list = new int[10];
memcpy(this->list, test.list, sizeof(int) * 10);
return *this;
}

O C++ e um a linguagem bem interresante e poderosa, mas, podemos atirarmos no pe se nao termos cuidado.

Edited by eatg75

Victarion seized the dusky woman by the wrist and pulled her to him.

Victarion - She will do it. Go pray to your red god. Light your fire, and tell me what you see.

Moqorro's dark eyes seemed to shine.

Moqorro - I see dragons.

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
×
×
  • 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.