Peixoto 0 Denunciar post Postado Julho 2, 2011 :( 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
Renato Utsch 24 Denunciar post Postado Julho 2, 2011 Leia o que o compilador retornou. Se não sabe inglês, use o google translator. Compartilhar este post Link para o post Compartilhar em outros sites
Bruno Alano 0 Denunciar post Postado Julho 2, 2011 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
Peixoto 0 Denunciar post Postado Julho 3, 2011 :( 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
Renato Utsch 24 Denunciar post Postado Julho 3, 2011 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
Peixoto 0 Denunciar post Postado Julho 3, 2011 :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
Renato Utsch 24 Denunciar post Postado Julho 4, 2011 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
Peixoto 0 Denunciar post Postado Julho 4, 2011 :( 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
Renato Utsch 24 Denunciar post Postado Julho 4, 2011 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
Peixoto 0 Denunciar post Postado Julho 5, 2011 :joia: Sensacional !!!! Nunca vi uma explicação melhor. Obrigado Compartilhar este post Link para o post Compartilhar em outros sites
Renato Utsch 24 Denunciar post Postado Julho 5, 2011 Valeu ;D Então, problema resolvido? Abraços :D Compartilhar este post Link para o post Compartilhar em outros sites