Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Peixoto

[Resolvido] Problema no uso de herança

Recommended Posts

:(

 

Veja o programa:

 

#include <iostream>
using namespace std;

class Circulo
{
 private:
         double Area,raio;
         static const double PI;
         double Area_Circulo();

public:
       Circulo (double r);
       void Mostra_Area();
       double Pega_raio (); // para pegar o valor do raio e
                                 //permitir acesso da classe derivada
};

class Medidas_Circunferencia : public Circulo
{
 private:  
        double Diametro;     
        double Diametro_Circunferencia();   
 public:
        Medidas_Circunferencia(double r):Circulo (r){};
        void Mostra_Medidas_Circunferencia();

};

Circulo::Circulo(double r)
       :Area(0)
       {
         raio=r;
       }

double Circulo::Pega_raio ()
{
  return (raio);
}

double Circulo::Area_Circulo()
{
  cout << "Area area do Circulo." << endl;    
  Area=(raio*raio)*PI; // Área do Circulo
  return (Area);
}

void Circulo::Mostra_Area()
{
    Area_Circulo();
    cout << Area << endl;
    return;
}

double Medidas_Circunferencia::Diametro_Circunferencia()
{

 Pega_raio(); //passa
 cout << "Diametro da circunferencia:" << endl;                       
 Diametro=2*raio;
 return(Diametro);
}

void Medidas_Circunferencia::Mostra_Medidas_Circunferencia()
{
    Diametro_Circunferencia();
    return;
}       

const double Circulo::PI=3.1416; //define a variável no
                                //escopo global

int main()
{
   Medidas_Circunferencia Medidas(15);
   Medidas.Mostra_Area();
    cout << endl;

   system ("pause");
   return 0;
}

 

Se os parâmetros-padrão de uma função membro tem de ser constantes (Soube disso depois ), então fiz:

 

double Circulo::Pega_raio ()
{
  return (raio);
}

 

busquei fazer de Pega_raio () apenas uma função de acesso para retornar raio, visando seu uso na derivada. Também tirei o acento colocado indevidamente.

 

Mesmo assim ocorreram os seguintes erros:

 

D:\Teste\heranca.cpp In member function `double Medidas_Circunferencia::Diametro_Circunferencia()':

8 D:\Teste\heranca.cpp `double Circulo::raio' is private

60 D:\Teste\heranca.cpp within this context

8 D:\Teste\heranca.cpp `double Circulo::raio' is private

60 D:\Teste\heranca.cpp within this context

 

Onde estou errando ?

Obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

Uma função não consegue acessar as variáveis da classe pertencente que são PRIVADAS. Caso deseje fazer funcionar, deixe as variáveis que você deseja utilizar como PROTECTED ou PUBLIC.

Compartilhar este post


Link para o post
Compartilhar em outros sites

:(

 

O código abaixo foi tirado do livro do DEITEL pág.529 - 531

 

#ifndef BASEPLUS_H
#define BASEPLUS_H

#include <string> // classe string padrão C++ 
using std::string;

#include "CommissionEmployee.h" // Declaração da classe CommissionEmployee

class BasePlusCommissionEmployee : public CommissionEmployee
{
public:
  BasePlusCommissionEmployee( const string &, const string &, 
     const string &, double = 0.0, double = 0.0, double = 0.0 );

  void setBaseSalary( double ); // configura o salário-base
  double getBaseSalary() const; // retorna o salário-base

  double earnings() const; // calcula os rendimentos
  void print() const; // imprime o objeto BasePlusCommissionEmployee
private:
  double baseSalary; // salário-base
}; // fim da classe BasePlusCommissionEmployee

#endif

 

#include <iostream>
using std::cout;

// Definição da classe BasePlusCommissionEmployee
#include "BasePlusCommissionEmployee.h"

// construtor
BasePlusCommissionEmployee::BasePlusCommissionEmployee( 
  const string &first, const string &last, const string &ssn, 
  double sales, double rate, double salary ) 
  // chama explicitamente o construtor da classe básica 
  : CommissionEmployee( first, last, ssn, sales, rate )
{
  setBaseSalary( salary ); // valida e armazena salário-base
} // fim do construtor BasePlusCommissionEmployee

// configura o salário-base
void BasePlusCommissionEmployee::setBaseSalary( double salary )
{
  baseSalary = ( salary < 0.0 ) ? 0.0 : salary;
} // fim da função setBaseSalary

// retorna o salário-base
double BasePlusCommissionEmployee::getBaseSalary() const
{
  return baseSalary;
} // fim da função getBaseSalary

// calcula os rendimentos
double BasePlusCommissionEmployee::earnings() const
{
  return getBaseSalary() + CommissionEmployee::earnings();
} // fim da função earnings

// imprime o objeto BasePlusCommissionEmployee
void BasePlusCommissionEmployee::print() const
{
  cout << "base-salaried ";

  // invoca a função print de CommissionEmployee
  CommissionEmployee::print();                 

  cout << "\nbase salary: " << getBaseSalary();
} // fim da função print

 

#include <iostream>
using std::cout;
using std::endl;
using std::fixed;

#include <iomanip>
using std::setprecision;

// Definição da classe BasePlusCommissionEmployee
#include "BasePlusCommissionEmployee.h" 

int main()
{
  // configura a formatação de saída de ponto flutuante
  cout << fixed << setprecision( 2 );

  { // inicia novo escopo                         
     CommissionEmployee employee1(                
        "Bob", "Lewis", "333-33-3333", 5000, .04 );
  } // termina o escopo                           

  cout << endl;
  BasePlusCommissionEmployee                                    
     employee2( "Lisa", "Jones", "555-55-5555", 2000, .06, 800 );

  cout << endl;
  BasePlusCommissionEmployee                                      
     employee3( "Mark", "Sands", "888-88-8888", 8000, .15, 2000 );
  cout << endl;
  return 0; 
} // fim de main

 

Na nota de rodapé da páginna 531, diz:

 

Dados private de classe básica são acessíveis a uma classe derivada via função-membro public ou protected herdada pela classe derivada.

 

Por isso estou tentando acessar os dados privados da classe básica via função de acesso. Se o livro informasse, que só poderia usar protectedjá teria feito isso. O probema é que não vejo onde estou errando. será que estou interpretando a citação erradamente ?

 

O livro inclusive diz, que acessar membros privados via função-membro publica, é uma forma de garantir o encapsulamento, e sugere que usar protected enfraque este conceito. Por conta desta citação, venho quebrando cabeça mais de duas semanas.

 

Se puderem mostrar onde meu código está errado - post 1, em oposição ao do DEITEL, agradeço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O livro está certo até certo ponto.

 

Ele está te confundindo.

 

O que acontece, é que dados privados da classe básica podem ser acessados por funções da classe básica (igual normalmente). Mas, se essas funções da classe básica que acessam membros privados dela forem protected ou public, eles serão herdados pela classe derivada, certo? Então a classe derivada pode chamar essa função public da classe básica, que então chamará os dados privados da classe básica.

 

Mas nunca uma classe derivada pode acessar os membros private de uma classe básica. Só os protected e public.

 

 

Entendeu?

 

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

:o

 

Após muita resistência, Eu Mudei

 

class Circulo
{
 private:
         double Area,raio;
         static const double PI;
         double Area_Circulo();
.
.
.

 

para

 

class Circulo
{
 protected:
         double Area,raio;
         static const double PI;
         double Area_Circulo();
.
.
.

 

e funcionou. Então pergunto qual o papel das funções de acesso numa classe base em relação classe derivada ? considerando a citação que você comentou.

 

Obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você deve ter escrevido algo errado.

 

Como assim qual o papel? Permitir que elementos fora da classe acessem elementos privados, ora ;D

 

E para que esconder os dados como privados? Para impedir acesso não intencional e não desejado a ela, evitando assim possíveis problemas em certos programas.

 

 

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

:(

 

Acho que compliquei. Vou formular melhor a questão.

 

Fiz a modificação para que a variável raio pudesse ser usada na classe derivada, sendo esta uma variável de classe básica. Isto me fez perceber, que os livros de C++, não explicam claramente a diferença entre public, protected e private. Esta diferença fica mais sutil, quando se trata de variáveis e funções membro.

 

A impressão que tive, foi que o uso de uma destas permissões de acesso para função-membro, funciona de um jeito, e para membro de dados de outro. Poderia explicar a diferença entre estas permissões de acesso com função-membro e membros de dados ? depois desta resposta poderei discutir meu avanço.

 

Obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites
Isto me fez perceber, que os livros de C++, não explicam claramente a diferença entre public, protected e private.

 

Está redondamente enganado. O que acontece é que o livro que você leu não é bom. Para falar a verdade, nenhum livro em português é bom para aprender uma linguagem de programação. Prefira os que estão em inglês. Se não sabe inglês, é bom que aprenda (e logo), pois é um requisito nos dias de hoje. Até o livro "C++ Fundamentos e Prática", tradução mal feita de um livro do Herbert Schildt faz questão de explicar (e muito bem) a diferença entre os 3.

 

Você não pode acessar uma variável private de uma classe básica pela classe derivada, espero que tenha entendido isso. Mas se declará-la como protected, só as classes derivadas poderão acessá-la.

 

 

Olha, você está entendendo tudo errado. Vamos voltar ao começo

 

----------------------------------------------------------------------------------------------------------

 

Uma classe pode ter seus dados e funções especificados como public, private ou protected.

 

Quando você especifica dados como public, qualquer função de fora da classe pode modificar.

 

class T {
   public:
   int x;
};

int main(void) {
   T teste;
   teste.x = 24;
   return 0;
}

 

Como pode ver, você pode modificar os dados públicos de uma classe de fora dela.

 

 

Agora, se os membros forem private, uma função de fora não pode modificá-los.

 

class T {
   private:
   int x;
};

int main(void) {
   T teste;
   teste.x = 24; // ERRO
   return 0;
}

 

Mas, se os dados forem especificados como protected, uma classe derivada pode modificá-los, mas funções e classes que não sejam derivadas (ou friend) não podem.

 

class T {
   protected:
   int x;
};

class U : public T {
   public:
   void modifyx(int valor) {
       x = valor; // CORRETO
   }
}

int main(void) {
   T teste;
   teste.x = 24; // ERRO
   return 0;
}

 

Mas nem uma classe derivada pode modificar os dados private de uma classe básica.

 

----

 

 

Agora, caso for chamar funções, tem uma coisa a mais. Uma função que esteja dentro da classe pode modificar os dados dentro dela, não importa se sejam private ou public.

 

class T {
   private:
   int x;

   public:
   void changex(int valor) {
       x = valor; // CORRETO
   }
};

int main(void) {
   T teste;
   teste.x = 24; // ERRADO
   teste.changex(24); // CORRETO
   return 0;
}

 

 

Então, uma classe derivada pode usar a função de controle da classe básica para chamar dados privados da mesma:

 

class T {
   private:
   int x;

   public:
   void changex(int valor) {
       x = valor; // CORRETO
   }
};

class U : public T {
   public:
   void changex2(int valor) {
       x = valor; // ERRADO
       changex(valor); // CORRETO
   }
};

int main(void) {
   T teste;
   teste.x = 24; // ERRADO
   teste.changex(24); // CORRETO
   return 0;
}

 

E o resto das regras é igual. Uma função public pode ser acessada por qualquer parte do código. Uma função protected pode ser acessada só pela classe e por derivadas, e uma função private só pode ser acessada diretamente pela classe.

 

 

Então, resumindo, na teoria não há diferenças na regra de acesso de dados e funções em uma classe, mas na prática há essa peculiaridade que você viu.

 

 

 

Agora entendeu?

 

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.