Ir ao conteúdo

C++ Programação C++ básica: classes


Ir à solução Resolvido por Ansi C,

Posts recomendados

Postado

Olá

 

Pessoal estou tendo problemas para chamar um método de uma classe em outra classe. Tipo, implementar um método da classe A para que ele utilize um método de uma classe B, isso antes de criar os objetos, somente nas definições de classes.  É possível fazer isso antes da criação do objeto? Gostaria que apontassem material ou vídeo que ensina a fazer isso.

 

valeu.

  • Curtir 1
Postado

Pra ficar mais claro vou postar o código e o erro que deu. Estou tentando resolver aquele problema do passeio do cavalo em POO criando os objetos tabuleiro e peça que irão se comunicar para que a peça (cavalo) possa visitar todas as casa sem repetir. Tenham em mente que estou só no começo e não implementei quase nada dos métodos.

 

Esse é o arquivo tabuleiro.h que contém a classe Tabuleiro.

using namespace std;

class Tabuleiro {

	//friend class Peca;

public:
	
	void desenhar(); //desenha o tabuleiro em seu estado atual
	void casasDisp(); //analisa as casas disponíveis
	void limpar(); //para limpar e atualizar a tela
	void setStatus();
	void getStatus();


private:

	int tabul[8][8] = {0};
	const int vetorMover[8][2] = {(-1, 2), ( 1, 2), ( 2, 1), ( 2,-1),
	  				              ( 1,-2), (-1,-2), (-2,-1), (-2, 1)}; //matriz com os vetores para movimento
	
};

 

Esse abaixo é a implementação dos métodos da classe e estão em um arquivo tabuleiro.cpp.

E o problema é aqui. Estou querendo utilizar o método posAtual() da classe Peca mas não estou sabendo como.

#include <iostream>
#include "tabuleiro.h"
using namespace std;


void Tabuleiro::desenhar(){

	int i, j;
	i = j = 0;
	while(i<8){
		while(j<8){
			cout << " " << Tabuleiro::tabul[i][j] << " ";
			j++;
		}
		j=0;
		i++;
		cout << endl;
	}
}

void Tabuleiro::casasDisp(){ //vai precisar saber a posição atual da peça

	int v2[1][3] = {0};
	friend class Peca::posAtual(v2); //marcador para marcar essa linha
	cout << v2[0][0] << v2[0][1] << v2[0][2];
}

void Tabuleiro::limpar(){
	system("cls");
}

void escolher(){

	
}

 

Aqui é a classe peça: peca.h

using namespace std;
class Peca{

public:
	
	friend class Tabuleiro;
	void escolher(); //método que verifica quais casas estão disponíveis e determina pra qual casa a peça irá
	void moverPeca(); //tem que ter parâmetro de entrada para saber para qual casa vai. O método escolher() fornecerá o parâmetro
	void retroceder(); //quando a peça não tiver casas disponíveis para ir deve retroceder um movimento
	void posAtual(int [1][3]); //passará/retornará a posição atual da peça

private:

	int histPos[64][3]; //histórico das posições
	int posAt[1][3]; //posição atual - terá uma coluna com o número do movimento, e mais duas com a linha e coluna q ocupa no tabuleiro
	const int vetorMover[8][2] = {(-1, 2), ( 1, 2), ( 2, 1), ( 2,-1),
						          ( 1,-2), (-1,-2), (-2,-1), (-2, 1)}; //matriz com os vetores para movimento

};

 

Aqui é a implementação de peça: peca.cpp

#include <iostream>
#include "peca.h"

using namespace std;

void Peca::posAtual(int v1[1][3]){
	int j = 0;
	while(j < 3){
		v1[1][j] = posAt[1][j];
		j++;
	}
}

 

E esse outro é o código que tem a função main, eu chamei de motor.cpp:

#include <iostream>
#include "tabuleiro.cpp"
#include "peca.cpp"

using namespace std;

int main(){

	Tabuleiro tabuleiro;

	tabuleiro.desenhar();

	system("pause");
	tabuleiro.limpar();

	tabuleiro.casasDisp();

	cout << "Sucesso!";
	return 0;
}

 

IMG DÚVIDA.jpg

Postado

esse constructo:

friend class Peca::posAtual(v2);

Não tem sentido. friend aparece na declaração das classes, nunca em outro lugar. Dentro do corpo de uma função então...

  • Solução
Postado

Olá!

Talvez me engane, mas sei que o operador :: [em palavras identificador de escopo] especifica o acesso dos módulos [ou classes se preferir] e, em específico de C++, um membro comum: é um membro declarado com a palavra-chave static.

  Em 02/01/2022 às 16:37, Cris.Pavani disse:
void Tabuleiro::casasDisp(){ //vai precisar saber a posição atual da peça

	int v2[1][3] = {0};
	friend class Peca::posAtual(v2); //marcador para marcar essa linha
	cout << v2[0][0] << v2[0][1] << v2[0][2];
}
Expandir  

 

Logo, erraria se igual abaixo, corrigido apenas a declaração arbitrária de friend

void Tabuleiro::casasDisp(){ //vai precisar saber a posição atual da peça

	int v2[1][3] = {0};
	/*friend class*/ Peca::posAtual(v2); //marcador para marcar essa linha
	cout << v2[0][0] << v2[0][1] << v2[0][2];
}

 

Exceto se posAtual(...)  é um membro static [comum]. Se entendi correto, a classe Peça é subordinada a tabuleiro, entretanto é necessário um objeto 'Peça' para acessar os membros [privados e logicamente públicos] ou método que é comum e friend [não sei o porquê de alguém fazer isso] com parâmetro Peça.

 

Entendi que pensou conseguir acesso dos membros simplesmente com a declaração friend; sem seu objeto.

[:)Não sei dizer como funcionaria: penso que não é assim que funciona.

Postado

@RPGStreamer Após fazer a alteração sugerida, dá um erro de que não existe objeto instanciado. Eu instanciei um objeto da classe Peca criando o objeto e compilou. Mas dai fica estranho porque fica um objeto criado dentro da classe tabuleiro, dentro do método. Mas eu quero instanciar somente no arquivo principal para rodar tudo entende? Quero um jeito de fazer com que a função do Tabuleiro "saiba" que tem que usar uma função da peça para fazer o que é preciso, que no caso é verificar quais casas estão disponíveis para próximo movimento do cavalo.

Postado

Acho que já sabe que tentou criar uma referência cíclica, com Peca usando Tabuleiro e Tabuleiro usando Peca.

 

Não funciona assim. 

 

E as declarações friend estão em lugares errados.

 

Considere que não há razão para Peca depender de Tabuleiro. A posição da peça, por exemplo, não importa para a peça. Apenas para o tabuleiro e para a lógica do jogo. Apenas troque o método de lugar.

 

  Em 02/01/2022 às 20:15, mauro_b disse:

Talvez me engane, mas sei que o operador :: [em palavras identificador de escopo] especifica o acesso dos módulos [ou classes se preferir] e, em específico de C++, um membro comum: é um membro declarado com a palavra-chave static

Expandir  

 

Nada tem a ver com static. Trata-se apenas do operador de resolução de escopo, descrito aqui na documentação em português, ou scope resolution operator

Postado
  Em 04/01/2022 às 14:41, arfneto disse:

Nada tem a ver com static. Trata-se apenas do operador de resolução de escopo, descrito aqui na documentação em português, ou scope resolution operator

Expandir  

Entretanto, o texto destacado no link acima tem o seguinte trecho.

image.png.a90c36b3b1b195a6bd4f59735d84b04d.png

 

Não há nada para interpretar.

 

  Em 02/01/2022 às 20:15, mauro_b disse:

Talvez me engane, mas sei que o operador :: [em palavras identificador de escopo] especifica o acesso dos módulos [ou classes se preferir] e, em específico de C++, um membro comum: é um membro declarado com a palavra-chave static.

Expandir  

 

Talvez a confusão seja porque nômeo membros estáticos com COMUM. De qualquer forma, essa discussão acabou para mim. 

 

Postado
  Em 04/01/2022 às 15:43, mauro_b disse:

Não há nada para interpretar.

Expandir  

 

image.png.077cda39ab11e3bce5f93a034344214e.png

 

 

Sim, se deve usar :: para acessar membros estáticos, já que eles não tem uma instância para definir o escopo. Mas nada diz aí sobre o contrário: nada diz aí que o operador :: seja usado apenas para acessar membros estáticos de classes. Há muitas razões para seu uso. Muitas vezes se usa apenas para ressaltar a origem, mesmo quando o escopo já está definido.

 

 

Postado
  Em 04/01/2022 às 17:34, arfneto disse:

sado apenas para acessar membros estáticos de classes

Expandir  

Ninguém, além de você, disse apenas, não coloque palavras onde não há e com isso eviti estender essa discussão desnecessariamente.

 

Postado
  Em 02/01/2022 às 20:15, mauro_b disse:

Talvez me engane, mas sei que o operador :: [em palavras identificador de escopo] especifica o acesso dos módulos [ou classes se preferir] e, em específico de C++, um membro comum: é um membro declarado com a palavra-chave static

Expandir  

 

Foi você, @mauro_b que escreveu isso. E pela ressalva já no início se vê que não estava seguro.  E não está correto. Apenas expliquei porque. Não é ideia minha. Trata-se da linguagem C++. Em especial o final do parágrafo 

 

  Em 02/01/2022 às 20:15, mauro_b disse:

em específico de C++, um membro comum: é um membro declarado com a palavra-chave static.

Expandir  

 

não faz sentido e mereceria redação mais elaborada.

 

Só comentei no sentido de esclarecer aos leitores do tópico.

 

  Em 04/01/2022 às 15:43, mauro_b disse:

De qualquer forma, essa discussão acabou para mim. 

Expandir  

 

Note que há um botão para tal  image.png.cf60a643c763c7c63e7b20f3986f0cc1.pnge pode apenas desmarcar em sua sessão.

 

  Em 04/01/2022 às 18:16, mauro_b disse:

Ninguém, além de você, disse apenas, não coloque palavras onde não há e com isso eviti estender essa discussão desnecessariamente

Expandir  

 

Leia e cite algo que mantenha o contexto da frase, por favor. 

 

Em C++: o operador de resolução de escopo é necessário (claro) para acessar métodos estáticos de uma classe, porque pode não haver uma instância para acessá-los. No entanto o operador não existe para isso. Esse era o sentido do apenas e está claro lá e obscuro no texto que escreveu e por isso deixei essas notas.

 

Poste um código sobre o que está tentando explicar...

 

Postado

@arfneto

  Em 04/01/2022 às 14:41, arfneto disse:

Acho que já sabe que tentou criar uma referência cíclica, com Peca usando Tabuleiro e Tabuleiro usando Peca.

 

Não funciona assim. 

 

E as declarações friend estão em lugares errados.

 

Considere que não há razão para Peca depender de Tabuleiro. A posição da peça, por exemplo, não importa para a peça. Apenas para o tabuleiro e para a lógica do jogo. Apenas troque o método de lugar.

Expandir  

 

 

Opa.

 

Gostaria que você só analisasse se o meu entendimento está correto: pelo que entendi não é possível criar um método que chame um método de um OUTRA classe antes da instanciação, ou seja, antes de criar um objeto. É isso?.

Caso eu queira utilizar um método que precise de um dado fornecido por função de outra classe então eu terei de programar na função main() após a instanciação das classes (criação dos objetos), correto?

 

Cara, obrigado pela atenção.

  • Curtir 1
Postado

Primeiro diz

  Em 04/01/2022 às 14:41, arfneto disse:

Nada tem a ver com static.

Expandir  

 

Depois diz 

  Em 04/01/2022 às 17:34, arfneto disse:

im, se deve usar :: para acessar membros estáticos, já que eles não tem uma instância para definir o escopo. Mas nada diz aí sobre o contrário: nada diz aí que o operador :: seja usado apenas para acessar membros estáticos de classes. Há muitas razões para seu uso. Muitas vezes se usa apenas para ressaltar a origem, mesmo quando o escopo já está definido.

Expandir  

 

Sugere que tem algo haver, porém não apenas, como se isso corrige algo.

 

 

  Em 04/01/2022 às 18:57, arfneto disse:

Leia e cite algo que mantenha o contexto da frase, por favor. 

 

Em C++: o operador de resolução de escopo é necessário (claro) para acessar métodos estáticos de uma classe, porque pode não haver uma instância para acessá-los. No entanto o operador não existe para isso. Esse era o sentido do apenas e está claro lá e obscuro no texto que escreveu e por isso deixei essas notas.

 

Poste um código sobre o que está tentando explicar...

Expandir  

Depois se corrige pela segundo vez. E de maneira alguma isso me ajudou.

Postado
  Em 04/01/2022 às 19:18, Cris.Pavani disse:

Gostaria que você só analisasse se o meu entendimento está correto: pelo que entendi não é possível criar um método que chame um método de um OUTRA classe. É isso?.

Expandir  

 

Sim, seu entendimento está correto.

 

O que não pode ter é uma referência cíclica.

 

  Em 04/01/2022 às 19:18, Cris.Pavani disse:

Caso eu queira utilizar um método que precise de um dado fornecido por função de outra classe então eu terei de programar na função main() após a instanciação das classes (criação dos objetos), correto?

Expandir  

 

Só a lógica do programa vai dizer. Pode ter classes internas também, em casos em que uma classe só tem sentido dentro de outra. Basta que a classe seja conhecida no momento em que é usada na outra. 

  Em 04/01/2022 às 19:20, mauro_b disse:

Depois se corrige pela segundo vez. E de maneira alguma isso me ajudou.

Expandir  

 

@mauro_b  sinto que não tenha ficado claro. Vou escrever um exemplo depois. 

  Em 04/01/2022 às 19:20, mauro_b disse:

Sugere que tem algo haver, porém não apenas, como se isso corrige algo.

Expandir  

 

Aparentemente você está confundindo causa com consequência.

  • Quando precisa acessar um método estático
  • E se não tem uma instância da classe

ENTÃO precisa do operador :: para indicar ao compilador onde está o método em questão.

 

Mas em muitos outros casos precisa ou pode usar esse operador nessa linguagem. O contrário não é verdadeiro.

 

De todo modo depois posto um exemplo.

 

 

Postado

Imagino que entenda esse exemplo, @mauro_b onde pode ver o que eu tentei explicar: funções e variáveis estáticas e o uso de
 

::


para identificar escopo. Inclusive para permitir acesso ao escopo global. ;) 

 

#include <iostream>

class ex1
{
   public:
    static int const valor = 42;
    int              outro;
    ex1() : outro(1){};
    ex1(int v) : outro(2){};

    static auto f1()
    {
        std::cerr << "valor: " << ex1::valor << "\n";
        return ex1::valor;
    };

    auto f2()
    {
        std::cerr << "valor: " << valor << " outro: " << outro << "\n";
        return valor + outro;
    };
};

auto f1()
{
    std::cerr << "(main) valor: " << ex1::valor << "\n";
    return ex1::valor + 22;
};

int main(void)
{
    std::cout << "Acessando via ::f1() " << ex1::f1() << "\n";
    ex1 um(42);
    std::cout << "Acessando via um.f1() " << um.f1() << "\n";
    ex1 outro;
    std::cout << "Acessando via outro.f1() " << outro.f1() << "\n";
    std::cout << "Acessando f1() global " << ::f1() << "\n";
    std::cout << "Valor da variavel estatica na classe = " <<
        ex1::valor << "\n";
}

 

Eis a saída

 

valor: 42
Acessando via ::f1() 42
valor: 42
Acessando via um.f1() 42
valor: 42
Acessando via outro.f1() 42
(main) valor: 42
Acessando f1() global 64
Valor da variavel estatica na classe = 42

 

Postado

@arfneto Imaginei que demostraria o static e o operador :: sem relação!

Porque quando alguém diz que algo não tem relação (ou "Nada tem a ver") é porque não tem mesmo!

 

E por qual motivo eu trouxe static para uma discussão de friend?

  Em 02/01/2022 às 16:37, Cris.Pavani disse:
void Tabuleiro::casasDisp(){ //vai precisar saber a posição atual da peça

	int v2[1][3] = {0};
	friend class Peca::posAtual(v2); //marcador para marcar essa linha
	cout << v2[0][0] << v2[0][1] << v2[0][2];
}
Expandir  

Por conta desta imagem a imagem abaixo e do trecho acima que me fez pensar; A autora corrigiu "friend class" na declaração, mas não pode acessar o método porque ele não é comum [ou estático]

 

image.png.6c24f9db379fd308849661a644cdf7cd.png

 

 

Sem essa imagem a discussão não existiria;

  • Confuso 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Mostrar mais  

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

Mostrar mais  
×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!