Implementar este código em C++ [RESOLVIDO]

1. Implementar este código em C++ [RESOLVIDO]

skjdeecedcnfncvnrfcnrncjvnjrnfvjcnjrjvcjrvcj
Londreslondres

(usa Parabola)

Enviado em 20/05/2024 - 15:49h

Classe A:
public class ClasseA {
private ClasseB aClasseB; //Nome Link
public ClasseA() {
}
//Ativa o link
public void setAClasseB(ClasseB b){
aClasseB = b;
}
}


Classe B:
public class ClasseB {
private ClasseA aClasseA; //Nome Link
public ClasseB(){
}
//Ativa o link
public void setAClasseA(ClasseA a){
aClasseA = a;
}
}


main:
public class Principal {
public static void main(String args[]){
ClasseA a = new ClasseA();
ClasseB b = new ClasseB();
a.setAClasseB(b); //Sua chamada é Obrigatória
b.setAClasseA(a); //Sua chamada é Obrigatória
}
}



O problema é que o C++ exige que as classes (e funções também) tenham uma ordem. Por exemplo, se a classe B quiser acessar a classe A, a classe A deve estar acima da classe B e vice-versa. No Java não há ordem.

Existe alguma forma de implementar este código em C++?


  


2. MELHOR RESPOSTA

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 27/05/2024 - 10:44h

Faz muitos dias mas vou rewsponder mesmo assim.

O nome disso é dependencia circular, no java o javac faz a parada de resolver pelo programador e por isso não tem todo o trabalho que tem em linguagem como no C.

Pra resolver isso vc terá de colocar cada class numa unidade de compilação (compiler unit) e ai compilar em separado e então juntar tudo no executável final.
Observe também que o construtor padrão de cada classe está sendo chamado e é melhor transformá-las em ponteiro.

Uma unidade de compilação nada mais é que um módulo, vc coloca a classe num headerque é um arquivo.h e o código real dela vai dentro de um arquivo.cpp e então vc compila com:
g++ -c classeA.cpp
g++ -c classeB.cpp
g++ -c main.cpp
Vai ser gerado 3 arquivos: classeA.o classeB.o e main.o
Pra juntar tudo num executável basta fazer:
g++ -o main classeA.o classeB.o main.o

Veja como é um header pra uma unidade de compilação:
Salve como arquivo classeA.h
#ifndef CLASSE_A //include guard, alguns compiladores modernos usam #pragma once
#define CLASSE_A

//declarando B antes de B aparecer no código
//observe que o B aqui não pode ser usado código diretamente no header
//exemplo: não dá pra fazer ClasseB b porque ai vc estará chamando o construtor padrão de ClasseB
//chamando ele antes mesmo de ClasseB vir a existir
class ClasseB;

class ClasseA {
private:
ClasseB *aClasseB; //ponteiro Link
public:
ClasseA();//construtor padrão
//Ativa o link
void setAClasseB(ClasseB *b);
};

#endif


Salve como arquivo classeA.cpp
#include "classeA.h"

ClasseA::ClasseA(){
aClasseB = nullptr;
}
//Ativa o link
void ClasseA::setAClasseB(ClasseB *b){
aClasseB = b;
}



Salve como arquivo header classeB.h
#ifndef CLASSE_B //include guard, alguns compiladores modernos usam #pragma once
#define CLASSE_B

//declarando ClasseA antes de ClasseA aparecer no código
//observe que o A aqui não pode ser usado código diretamente no header
//exemplo: não dá pra fazer "ClasseA a;" porque ai vc estará chamando o construtor padrão de ClasseA
//chamando ele antes mesmo de ClasseA vir a existir
class ClasseA;

class ClasseB {
private:
ClasseA *aClasseA; //ponteiro Link
public:
ClasseB();//construtor padrão
//Ativa o link
void setAClasseA(ClasseA *a);
};

#endif


Salve como arquivo classeB.cpp
#include "classeB.h"

ClasseB::ClasseB(){
aClasseA = nullptr;
}
//Ativa o link
void ClasseB::setAClasseA(ClasseA *a){
aClasseA = a;
}


Agora o main:
#include "classeA.h"
#include "classeB.h"

int main () {
ClasseA a;
ClasseB b;

//seta a ClasseB em ClasseA
a.setAClasseB(&b);
//seta a ClasseA em ClasseB
b.setAClasseA(&a);
return 0;
}


Observe que ao criar uma unidade de compilação pra cada classe, vc pode incluir o header dela dentro do outro arquivo cpp:
Exemplo, se dentro do arquivo classeB.cpp vc quiser fazer uma chamada a alguma função de aClasseA, basta chamar normalmente pelo ponteiro, mas pra funcionar é preciso incluir o header classeA.h dentro do módulo classeB.cpp.

Se modificar qualquer um desses arquivo é necessário recompilar somente ele. Exemplo, caso modifique o main, então, reexecute o:
g++ -c main.cpp
seguido pelo:
g++ -o main ClasseA.o ClasseB.o main.o

Use um makefile para automatizar o processo ou aprenda sobre o cmake e economize tempo.


https://nerdki.blogspot.com/ acessa ai, blog dedicado Paranóia!
https://github.com/cpusam com o bug fix vem a perfeição!

3. Re: Implementar este código em C++ [RESOLVIDO]

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 20/05/2024 - 15:49h

Sim, é possível implementar esse código em C++ utilizando declarações antecipadas das classes. Abaixo está o código atualizado com as declarações antecipadas das classes:

```cpp
class ClasseB;

class ClasseA {
private:
ClasseB* aClasseB; // Nome Link

public:
ClasseA();
// Ativa o link
void setAClasseB(ClasseB* b);
};

class ClasseB {
private:
ClasseA* aClasseA; // Nome Link

public:
ClasseB();
// Ativa o link
void setAClasseA(ClasseA* a);
};

ClasseA::ClasseA() {
}

void ClasseA::setAClasseB(ClasseB* b) {
aClasseB = b;
}

ClasseB::ClasseB() {
}

void ClasseB::setAClasseA(ClasseA* a) {
aClasseA = a;
}

class Principal {
public:
static void main(std::string args[]){
ClasseA a = ClasseA();
ClasseB b = ClasseB();
a.setAClasseB(&b); // Sua chamada é Obrigatória
b.setAClasseA(&a); // Sua chamada é Obrigatória
}
};
```

Dessa forma, as classes ClasseA e ClasseB podem


4. Re: Implementar este código em C++ [RESOLVIDO]

skjdeecedcnfncvnrfcnrncjvnjrnfvjcnjrjvcjrvcj
Londreslondres

(usa Parabola)

Enviado em 28/05/2024 - 16:18h

SamL escreveu:

Faz muitos dias mas vou rewsponder mesmo assim.

O nome disso é dependencia circular, no java o javac faz a parada de resolver pelo programador e por isso não tem todo o trabalho que tem em linguagem como no C.

Pra resolver isso vc terá de colocar cada class numa unidade de compilação (compiler unit) e ai compilar em separado e então juntar tudo no executável final.
Observe também que o construtor padrão de cada classe está sendo chamado e é melhor transformá-las em ponteiro.

Uma unidade de compilação nada mais é que um módulo, vc coloca a classe num headerque é um arquivo.h e o código real dela vai dentro de um arquivo.cpp e então vc compila com:
g++ -c classeA.cpp
g++ -c classeB.cpp
g++ -c main.cpp
Vai ser gerado 3 arquivos: classeA.o classeB.o e main.o
Pra juntar tudo num executável basta fazer:
g++ -o main classeA.o classeB.o main.o

Veja como é um header pra uma unidade de compilação:
Salve como arquivo classeA.h
#ifndef CLASSE_A //include guard, alguns compiladores modernos usam #pragma once
#define CLASSE_A

//declarando B antes de B aparecer no código
//observe que o B aqui não pode ser usado código diretamente no header
//exemplo: não dá pra fazer ClasseB b porque ai vc estará chamando o construtor padrão de ClasseB
//chamando ele antes mesmo de ClasseB vir a existir
class ClasseB;

class ClasseA {
private:
ClasseB *aClasseB; //ponteiro Link
public:
ClasseA();//construtor padrão
//Ativa o link
void setAClasseB(ClasseB *b);
};

#endif


Salve como arquivo classeA.cpp
#include "classeA.h"

ClasseA::ClasseA(){
aClasseB = nullptr;
}
//Ativa o link
void ClasseA::setAClasseB(ClasseB *b){
aClasseB = b;
}



Salve como arquivo header classeB.h
#ifndef CLASSE_B //include guard, alguns compiladores modernos usam #pragma once
#define CLASSE_B

//declarando ClasseA antes de ClasseA aparecer no código
//observe que o A aqui não pode ser usado código diretamente no header
//exemplo: não dá pra fazer "ClasseA a;" porque ai vc estará chamando o construtor padrão de ClasseA
//chamando ele antes mesmo de ClasseA vir a existir
class ClasseA;

class ClasseB {
private:
ClasseA *aClasseA; //ponteiro Link
public:
ClasseB();//construtor padrão
//Ativa o link
void setAClasseA(ClasseA *a);
};

#endif


Salve como arquivo classeB.cpp
#include "classeB.h"

ClasseB::ClasseB(){
aClasseA = nullptr;
}
//Ativa o link
void ClasseB::setAClasseA(ClasseA *a){
aClasseA = a;
}


Agora o main:
#include "classeA.h"
#include "classeB.h"

int main () {
ClasseA a;
ClasseB b;

//seta a ClasseB em ClasseA
a.setAClasseB(&b);
//seta a ClasseA em ClasseB
b.setAClasseA(&a);
return 0;
}


Observe que ao criar uma unidade de compilação pra cada classe, vc pode incluir o header dela dentro do outro arquivo cpp:
Exemplo, se dentro do arquivo classeB.cpp vc quiser fazer uma chamada a alguma função de aClasseA, basta chamar normalmente pelo ponteiro, mas pra funcionar é preciso incluir o header classeA.h dentro do módulo classeB.cpp.

Se modificar qualquer um desses arquivo é necessário recompilar somente ele. Exemplo, caso modifique o main, então, reexecute o:
g++ -c main.o
seguido pelo:
g++ -o main ClasseA.o ClasseB.o main.o

Use um makefile para automatizar o processo ou aprenda sobre o cmake e economize tempo.


https://nerdki.blogspot.com/ acessa ai, blog dedicado Paranóia!
https://github.com/cpusam com o bug fix vem a perfeição!


Resolveu o meu problema.

Só mais uma pergunta: é possível fazer o mesmo com funções?


5. Re: Implementar este código em C++ [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 28/05/2024 - 17:15h

Londreslondres escreveu:

Só mais uma pergunta: é possível fazer o mesmo com funções?

Sim, só que no caso das funções muda um pouco mais:
--vc precisa declarar a definição da função no header (arquivo .h)
--usar a palavra extern pra indicar que a definição dela (o código da função]) estará em outro módulo.

Ou seja, o header guarda a definição que vc inclui em qualquer outro arquivo, e o cpp guarda o corpo da função.

Bora pro exemplo:
No header vc tem que colocar as includes guards ou o #pragma once, este último depende do compilador e versão do c++.

Salve como arquivo meuModulo.h
#ifndef MEU_MODULO_H
#define MEU_MODULO_H

//abaixo é a definição da função
//obviamente os parametros não precisam ser só do tipo int
extern void funcProcedimento(int a, int b, int *c);
//define a função somar, observe que a função funcProcedimento enxerga esta função abaixo via inclusão do header
extern int somar(int a, int b);

#endif


Daí vc coloca o código das funções como esse:
Salve o conteúdo como meuModulo.cpp
//inclui as definições das funções
#include "meuModulo.h"

//faz o corpo da função funcProcedimento()
void funcProcedimento(int a, int b, int *c) {
*c = somar(a, b);
}

// agora faz o corpo da função somar()
int somar(int a, int b) {
return a + b;
}


E depois vc compila com:
g++ -c meuModulo.cpp
Depois para usar as funções em outro projeto, vc compila com:
g++ -o main main.cpp meuModulo.o
Observe que essa é uma compilação estática, onde todo o c[odigo executável do meuModulo.o está sendo inserido no executável 'main'].
E também veja que o main.cpp está fazendo uso de alguma função do meuModulo.o

Exemplo de uso como mainModulo.cpp
#include<iostream>
#include <cstdlib>
#include "meuModulo.h" //inclui seu header

int main(int argc, char **args) {
int a = atoi(args[1]);
int b = atoi(args[2]);
std::cout<<"soma de '"<<a<<"' com '"<<b<<"' eh "<<somar(a, b)<<std::endl;
int c = 0;
funcProcedimento(a, b, &c);
std::cout<<"OU por ponteiro:\n\tsoma de '"<<a<<"' com '"<<b<<"' eh "<<c<<std::endl;

return 0;
}

Compile com:
g++ -o main main.cpp meuModulo.o
Rode com:
./main 31 69
Vai mostrar uma saída como:
soma de '31' com '69' eh 100
OU por ponteiro:
soma de '31' com '69' eh 100



6. Re: Implementar este código em C++ [RESOLVIDO]

Jean César
dark777

(usa Linux Mint)

Enviado em 29/05/2024 - 00:09h


Londreslondres escreveu:

SamL escreveu:

Faz muitos dias mas vou rewsponder mesmo assim.

O nome disso é dependencia circular, no java o javac faz a parada de resolver pelo programador e por isso não tem todo o trabalho que tem em linguagem como no C.

Pra resolver isso vc terá de colocar cada class numa unidade de compilação (compiler unit) e ai compilar em separado e então juntar tudo no executável final.
Observe também que o construtor padrão de cada classe está sendo chamado e é melhor transformá-las em ponteiro.

Uma unidade de compilação nada mais é que um módulo, vc coloca a classe num headerque é um arquivo.h e o código real dela vai dentro de um arquivo.cpp e então vc compila com:
g++ -c classeA.cpp
g++ -c classeB.cpp
g++ -c main.cpp
Vai ser gerado 3 arquivos: classeA.o classeB.o e main.o
Pra juntar tudo num executável basta fazer:
g++ -o main classeA.o classeB.o main.o

Veja como é um header pra uma unidade de compilação:
Salve como arquivo classeA.h
#ifndef CLASSE_A //include guard, alguns compiladores modernos usam #pragma once
#define CLASSE_A

//declarando B antes de B aparecer no código
//observe que o B aqui não pode ser usado código diretamente no header
//exemplo: não dá pra fazer ClasseB b porque ai vc estará chamando o construtor padrão de ClasseB
//chamando ele antes mesmo de ClasseB vir a existir
class ClasseB;

class ClasseA {
private:
ClasseB *aClasseB; //ponteiro Link
public:
ClasseA();//construtor padrão
//Ativa o link
void setAClasseB(ClasseB *b);
};

#endif


Salve como arquivo classeA.cpp
#include "classeA.h"

ClasseA::ClasseA(){
aClasseB = nullptr;
}
//Ativa o link
void ClasseA::setAClasseB(ClasseB *b){
aClasseB = b;
}



Salve como arquivo header classeB.h
#ifndef CLASSE_B //include guard, alguns compiladores modernos usam #pragma once
#define CLASSE_B

//declarando ClasseA antes de ClasseA aparecer no código
//observe que o A aqui não pode ser usado código diretamente no header
//exemplo: não dá pra fazer "ClasseA a;" porque ai vc estará chamando o construtor padrão de ClasseA
//chamando ele antes mesmo de ClasseA vir a existir
class ClasseA;

class ClasseB {
private:
ClasseA *aClasseA; //ponteiro Link
public:
ClasseB();//construtor padrão
//Ativa o link
void setAClasseA(ClasseA *a);
};

#endif


Salve como arquivo classeB.cpp
#include "classeB.h"

ClasseB::ClasseB(){
aClasseA = nullptr;
}
//Ativa o link
void ClasseB::setAClasseA(ClasseA *a){
aClasseA = a;
}


Agora o main:
#include "classeA.h"
#include "classeB.h"

int main () {
ClasseA a;
ClasseB b;

//seta a ClasseB em ClasseA
a.setAClasseB(&b);
//seta a ClasseA em ClasseB
b.setAClasseA(&a);
return 0;
}


Observe que ao criar uma unidade de compilação pra cada classe, vc pode incluir o header dela dentro do outro arquivo cpp:
Exemplo, se dentro do arquivo classeB.cpp vc quiser fazer uma chamada a alguma função de aClasseA, basta chamar normalmente pelo ponteiro, mas pra funcionar é preciso incluir o header classeA.h dentro do módulo classeB.cpp.

Se modificar qualquer um desses arquivo é necessário recompilar somente ele. Exemplo, caso modifique o main, então, reexecute o:
g++ -c main.o
seguido pelo:
g++ -o main ClasseA.o ClasseB.o main.o

Use um makefile para automatizar o processo ou aprenda sobre o cmake e economize tempo.


https://nerdki.blogspot.com/ acessa ai, blog dedicado Paranóia!
https://github.com/cpusam com o bug fix vem a perfeição!


Resolveu o meu problema.

Só mais uma pergunta: é possível fazer o mesmo com funções?



aguamole escreveu:

Um, então use o algoritmo "zip" esse é o único que eu sei que suporta atualização e deletar arquivos compactados. Ou você pode usar outro e descompactar e excluir de dps reempacotar.
O algoritmo que mais da compressão é o LZMA que é o algoritmo usado pelo XZ.
Quando vc escreveu backup eu achei que vc ia fazer isso com script.


@SamL encontrei este POST e ao tentar acessar o seu blog logado pela minha conta não dá acesso por que?


wiki.anon


7. Re: Implementar este código em C++ [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 29/05/2024 - 10:37h


dark777 escreveu:
@SamL encontrei este POST e ao tentar acessar o seu blog logado pela minha conta não dá acesso por que?

É que eu fechei o blog, mas os links ainda estão na minha assinatura. Nesse blog eu escrevia muita bobagem e pra não ficar espalhando raiva por ai, achei melhor encerrá-lo, pretendo voltar com ele outra hora mas com textos e ideias mais leves.

Falando nisso, tu me deu gatilho de iniciar outro blog, já tava com a ideia em mente faltava só um toque.
Segue ele:
https://tutorialprofissa.blogspot.com/
Estou planejando ainda as postagens, mas será só referente a aprendizado e coisas legais de aprender.


https://nerdki.blogspot.com/ acessa ai, blog dedicado Paranóia!
https://github.com/cpusam com o bug fix vem a perfeição!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts