C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to call protected pure virtual ancestor funcs from frien

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Siegfried Heintze
Guest





PostPosted: Sat May 19, 2007 1:41 pm    Post subject: How to call protected pure virtual ancestor funcs from frien Reply with quote



I have a (surprise!) stack class and I want to implement a compare function
that compares two stacks for equality. What I have below works, but MS
Visual C++ 6 requires that I declare ISTACK<TYPE>::getData public! Arghhh!
Those pure virtual getData functions should be protected! How do I make
them
protected? MSVC 6 gives me syntax errors if I don't make them public! Is
this a bug in the compiler or a bug in the C++ specification? Is there a
fix
other than declaring them public and violating the fundemental concept of a
stack? I tried implementing compare as a member function but then it could
not access the private or protected parts of the stack that is an argument
to the compare member function. Is that conistent with the C++ spec?

Thanks,
Siegfried

template<typename TYPE>
class ISTACK{
public:
virtual TYPE pop() = 0; //!< Remove the
last element.
virtual TYPE top() const=0; //!< Copy the
last
element but do not remove it.

public: // should be protected: not public!
virtual TYPE* getData()=0;
virtual const TYPE* getData() const=0;
};

template<typename TYPE, int SIZE, char SEP=10>
class STACK : public ISTACK<TYPE> // abstract interface
{
public:
STACK( ){ len = 0; push(); };
STACK(TYPE a ){ len = 0; push(a); };

//template<typename TYPE>
friend int compare(const ISTACK<TYPE>& left, const ISTACK<TYPE>&
right)
{
int lenLeft = left.getLength();
int lenRight = right.getLength();
int len = lenLeft < lenRight ? lenLeft : lenRight; // compute
the
min
if(lenLeft == 0 && lenRight == 0)
{
}
else
{
const TYPE*pLeft = left.getData();
const TYPE*pRight = right.getData();
for(int ii = 0; ii < len; ++ii)
{
if(pLeft[ii] != pRight[ii])
{
return pLeft[ii] - pRight[ii];
}
} // they are equal except for extra cells
if(lenLeft != lenRight)
{
return lenLeft - lenRight;
}
}
return 0;
}

protected:
TYPE* getData() { return state; }
private:
const TYPE* getData() const { return state; }



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Daniel Krügler
Guest





PostPosted: Sat May 19, 2007 6:03 pm    Post subject: Re: How to call protected pure virtual ancestor funcs from Reply with quote



On 19 Mai, 15:41, "Siegfried Heintze" <siegfr...@heintze.com> wrote:
Quote:
[..] What I have below works, but MS
Visual C++ 6 requires that I declare ISTACK<TYPE>::getData public! Arghhh!
Those pure virtual getData functions should be protected! How do I make
them
protected? MSVC 6 gives me syntax errors if I don't make them public! Is
this a bug in the compiler or a bug in the C++ specification?

VC6 is correct. Please look carefully at your code: Your
friend compare function is part of the STACK template,
not of the base class ISTACK. Friendship and inheritance
are independent concepts, so you cannot expect that a
friend of a derived class can access protected parts
of the its base *via a base class* instance! If the
friend would try to access getData via a STACK instance,
no such error would have occurred. 11.5/1 explains the
details of your situation.

Funnily, your compare function uses only ISTACK arguments,
so the basic question arises: Why did you not provide it
as friend function of the ISTACK template? Indeed this
would be the most reasonable decision.

Since you provided source code, here are some further
points:

- The "abstract" base class misses a virtual d'tor.
- The source code as is does not compile, because the
compare functions uses several unavailable members of
ISTACK. If you want any serious answers to your question,
your snippet should be complete and should also not have
unnecessary members (e.g. missing: len,state in STACK;
getLength() in ISTACK).
- It's quite unusual to use full UPPERCASE letter names
for any non-macro entity in C/C++.

Quote:
Is there a fix other than declaring them public and violating the fundemental concept of a
stack? I tried implementing compare as a member function but then it could
not access the private or protected parts of the stack that is an argument
to the compare member function. Is that conistent with the C++ spec?

Move compare into the ISTACK template, as explained above.
You also could have made compare a normal member function
of ISTACK (and not STACK), because every member has
access to the protected and private parts of its class,
see 11/1, 2nd bullet:

"- protected; that is, its name can be used only by members
and friends of the class in which it is declared, and by
members and friends of classes derived from this class (see 11.5)."

Personally I would prefer the non-member friend function
here, because of it's argument symmetry.

Greetings from Bremen,

Daniel Krügler




--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.