protected member OOP question
I got one question about protected members.
Here is the code:
Code:
#include <iostream>
using namespace std;
class osnovna
{
protected:
int test;
};
class izvedena : private osnovna
{
public:
void funkcija()
{
cin>>test;
cout<<test;
}
};
class izvedena1 : public izvedena
{
public:
void tesit()
{
cin>>test;
cout<<test<<endl;
}
};
int main()
{
izvedena dva;
dva.funkcija();
system("PAUSE");
return 0;
}
Why when I write izvedena : public osnovna, or izvedena : protected osnovna the izvedena1 class can access the variable test and with private not?
Can somebody elaborate please?
Thanks in advance.
Re: protected member OOP question
Because when you write
Code:
izvedena : private osnovna
the member test becomes private in izvedena. So, all derived classes from izvedena cannot access that member.
You should do some more reading, like here:
http://www.parashift.com/c++-faq-lit...heritance.html
Re: protected member OOP question
Quote:
Originally Posted by StGuru
Why when I write izvedena : public osnovna, or izvedena : protected osnovna the izvedena1 class can access the variable test and with private not?
All the members inherited from a private base class become private members of the derived class, so it is as if you declared test as private in izvedena.
Re: protected member OOP question
Thanks for the replies. And why when I put protected it works? Is it inherited like protected member?
I got another question. Why the inherited class does not inherit the private members of the original class?
Re: protected member OOP question
Quote:
Originally Posted by StGuru
And why when I put protected it works? Is it inherited like protected member?
Yes.
Quote:
Originally Posted by StGuru
Why the inherited class does not inherit the private members of the original class?
They do, but those members are not accessible.
Re: protected member OOP question
Quote:
Originally Posted by
laserlight
Yes.
They do, but those members are not accessible.
They are not accessible by any possible way? Is there any way that I can access them?
Re: protected member OOP question
With a help of interface methods, for example...
Code:
#include <iostream>
using namespace std;
class osnovna
{
public:
int get_test( void ) { return test; }
protected:
int test;
};
class izvedena : private osnovna
{
public:
void funkcija() // it would be better to call this a 'method'
{
// cin>>test;
cout<<get_test();
}
};
/*
class izvedena1 : public izvedena
{
public:
void tesit()
{
// cin>>test;
cout<<test<<endl;
}
};
*/
int main()
{
izvedena dva;
dva.funkcija();
system("PAUSE");
return 0;
}
Re: protected member OOP question
Re: protected member OOP question
I noticed when I put class izvedena : public osnovna then the protected member test becomes again protected, but if I put private it becomes private inside the inherited class.
Re: protected member OOP question
IMHO you should never use protected data members.
You should consider the 3 sections of a class as :-
public :- The interface to calling code. Defines the behaviour of the object.
protected :- The interface to derived classes. This is where functions needed by derived classes but not by client code live.
private :- The implementation details area. This is where your data members and internal to the class functions should be.
You should view both the public and protected sections as interface sections. There should be no implementation in an interface. Any data member is very much an implementation detail.
Re: protected member OOP question
Quote:
Originally Posted by
Russco
IMHO you should never use protected data members.
You should consider the 3 sections of a class as :-
public :- The interface to calling code. Defines the behaviour of the object.
protected :- The interface to derived classes. This is where functions needed by derived classes but not by client code live.
private :- The implementation details area. This is where your data members and internal to the class functions should be.
You should view both the public and protected sections as interface sections. There should be no implementation in an interface. Any data member is very much an implementation detail.
I always hear this being said, but when I think about applying it to my programs, I realise that I've have to create so many Get and Set functions to access the data that I just made private that it's not worth it...
Re: protected member OOP question
Quote:
Originally Posted by
Mybowlcut
I always hear this being said, but when I think about applying it to my programs, I realise that I've have to create so many Get and Set functions to access the data that I just made private that it's not worth it...
It's a violation of the most fundamental OOP rule: Hide as much as you can. It's a rather bad thing when you write a library.
Consider using preprocessor to make private fields public only on debugging stage of development(1), and generalize your classes(2) - write generalized methods and/or provide a flexible interface.
In most cases all the inheritance hierarchy works as all at once. E.g. when you have a class Vehicle you already know that you need Bike, Car and Ship, but not, say, Plane. So you know what to show and what to hide from derived classes.
Re: protected member OOP question
Quote:
Originally Posted by
andrey_zh
It's a violation of the most fundamental OOP rule: Hide as much as you can. It's a rather bad thing when you write a library.
I understand that, but like I said, I don't see how making everything private is beneficial when in most cases you have to make Get/Set functions to get around it anyway.
Quote:
Originally Posted by
andrey_zh
Consider using preprocessor to make private fields public only on debugging stage of development(1), and generalize your classes(2) - write generalized methods and/or provide a flexible interface.
In most cases all the inheritance hierarchy works as all at once. E.g. when you have a class Vehicle you already know that you need Bike, Car and Ship, but not, say, Plane. So you know what to show and what to hide from derived classes.
Not really sure what you mean. Care to post a code sample?
Re: protected member OOP question
Quote:
Originally Posted by Mybowlcut
I don't see how making everything private is beneficial when in most cases you have to make Get/Set functions to get around it anyway.
If you need to have getters and setters in most cases, then it implies that in many cases you have a poor class design that does not provide a relevant class interface. In those cases where there is a genuine need for getters and setters, they have an advantage over providing direct access to the member variable since the option of changing the member variable without breaking client code remains.
Re: protected member OOP question
Quote:
Originally Posted by
laserlight
If you need to have getters and setters in most cases, then it implies that in many cases you have a poor class design that does not provide a relevant class interface. In those cases where there is a genuine need for getters and setters, they have an advantage over providing direct access to the member variable since the option of changing the member variable without breaking client code remains.
I'm going through my code trying to find an example but I'm not having much luck... when I find one I'll post it here. But basically, my class design isn't "poor" as I don't encounter any problems with it. Perhaps with a large library with many clients like andrey_zh mentioned, it would be a bigger issue.
Re: protected member OOP question
We have macros that create the get and set functions for you. Here's an example of one of them.
Code:
// Purpose:
// HAS_A is used for quickly creating a private class member variable with corresponding
// public Get and Set functions.
//
// Usage:
// HAS_A( type , name )
// Example: HAS_A(int, Count)
// The above example expands to the following code:
//
// private:
// int m_Count;
// public:
// const int & GetCount () const { return m_Count; }
// void SetCount(const int & inValue) { m_Count = (( int &)inValue); }
//
// Notes:
// 1) HAS_A can change the scope of members and methods declared after it. In the following
// example the declaration of X is public, not private.
//
// private:
// HAS_A(int, Count)
// int X;
//
// For this reason HAS_A is usually used at the end of a class.
//
// 2) HAS_A is case sensitive. The following example creates Getcount and Setcount methods,
// not GetCount and SetCount.
//
// HAS_A(int, count)
#define HAS_A( inType, inName )\
private: \
inType m_ ## inName; \
public: \
virtual const inType & inName () const { return m_ ## inName; } \
virtual void inName(const inType & inValue) { m_ ## inName = (( inType &)inValue); }
Re: protected member OOP question
Hi GCDEF,
Reading your post I read the line "void inName(const inType & inValue) { m_ ## inName = (( inType &)inValue); }"
and I'm wondering why you used the "( inType &)" cast: given that a cast to a reference is always an l-value its effect should be to allow assignment operator with non const reference argument, am I right ? if yes, why do you feel it necessary?
Re: protected member OOP question
Quote:
Originally Posted by
GCDEF
We have macros that create the get and set functions for you. Here's an example of one of them.
Code:
// Purpose:
// HAS_A is used for quickly creating a private class member variable with corresponding
// public Get and Set functions.
//
// Usage:
// HAS_A( type , name )
// Example: HAS_A(int, Count)
// The above example expands to the following code:
//
// private:
// int m_Count;
// public:
// const int & GetCount () const { return m_Count; }
// void SetCount(const int & inValue) { m_Count = (( int &)inValue); }
//
// Notes:
// 1) HAS_A can change the scope of members and methods declared after it. In the following
// example the declaration of X is public, not private.
//
// private:
// HAS_A(int, Count)
// int X;
//
// For this reason HAS_A is usually used at the end of a class.
//
// 2) HAS_A is case sensitive. The following example creates Getcount and Setcount methods,
// not GetCount and SetCount.
//
// HAS_A(int, count)
#define HAS_A( inType, inName )\
private: \
inType m_ ## inName; \
public: \
virtual const inType & inName () const { return m_ ## inName; } \
virtual void inName(const inType & inValue) { m_ ## inName = (( inType &)inValue); }
I have a few questions about that:
- What about if you choose to make GetCount return a temporary?
- What if the Get/Set functions need to be virtual?
- Do they have to be inline?
- Also, back onto the subject of protected, do you have a macro for creating protected members that only derived classes can access with Get/Set functions? Which brings me to another question...
- Not all members will need read and write access, right?
Some of my questions are a bit silly, but I'm curious as to the point where you stop using the macro and start declaring odd Get/Set functions here and there that are virtual or exist under different access modifiers. I guess I like to be consistent in that I rarely create inline functions. The macro idea is a good one though, but I can't help but think that this is where some automated tool would come in handy (like VS Snippets which AFAIK don't exist for C++) so that you don't have code littered with macros but at the same time don't have to go around manually typing 2 function declarations and definitions for every member.