Solved

Access to Protected Member Within Class

Posted on 1998-08-22
19
226 Views
Last Modified: 2010-04-01
I am getting a compile-time error on the following short C++ program:

class T {
protected:
 typedef struct {
  int a;
 } s1;
 typedef struct {
  s1 b;
 } s2;
}
main ()
{
 return 1;
}

The compile error shown is 'unable to reference member T::s1 in T::s2, protected member' and it occurs on the line 's1 b;'.

Can somebody verify that this is the proper behavior by ANSI standards? I don't understand why this is an error as the reference to the struct s1 is within the same class?  Thanks!
0
Comment
Question by:jerrydy
  • 7
  • 3
  • 3
  • +5
19 Comments
 

Author Comment

by:jerrydy
ID: 1170993
Edited text of question
0
 

Author Comment

by:jerrydy
ID: 1170994
Edited text of question
0
 
LVL 2

Expert Comment

by:prasanth
ID: 1170995
I just tried it with MS VC++ 5 and it worked fine. Which compiler are you using?
0
 

Author Comment

by:jerrydy
ID: 1170996
Prasanth,

I'm using HP-UX 10.10 after the y2k patches have been installed.  My code originally worked before the patches to make the compiler y2k compliant was installed.  When I wrote HP's tech support about the problem, the reply I got was my code was not ANSI-compliant and the compiler error was correct.

Would somebody please help me verify if the code is ANSI-compliant?  Is there a web site that contains all the rules that must be followed for C++ code to be ANSI compliant?

I'm also curious to know if other C++ compilers (any platform, ANSI compliant or not) will compile the code.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1170997
Compiles OK here (MSVC 4.2b) but you forgort a semicolon after the closing bracket of the class definition.  Maybe that's your problem?
0
 
LVL 7

Expert Comment

by:Motaz
ID: 1170998
Protected members are accessed only inside the scope of class. So if you want to access it with main code for example; you must declare it as a public.

Motaz, from Sudan
0
 
LVL 3

Expert Comment

by:xyu
ID: 1170999
OK... lets talk about nested classes by standard

..
Like a member function, a friend  function defined within a nested class is in the lexical scope of that class; it obeys the same rules for name binding as a static member  function  of that class and has no special access rights to members of an enclosing class...
.
etc.

So by the standard the nested class doesn't have any additional rights to enclosong class  :)... but You can easily solve this "Problem" like that... (i wasn't able to check it currently.. because VC 5.x has a bug and compiles Your example ok in original way...)

class T {
protected:
 typedef struct {
  int a;
 } s1;
 friend s1;

 typedef struct {
  s1 b;
 } s2;
 friend s1;
} ;
main ()
{
 return 1;
}
0
 

Author Comment

by:jerrydy
ID: 1171000
Xyu,

I don't think the text you quoted will apply here, not so much because the code didn't have any friend or static functions, but because the struct T::s2 doesn't need any special access rights at all.  T::s1 was declared before T::s2, and both structs are members of the same class, so in my thinking, T::s2 SHOULD be able to reference T::s1.

The error violates the C++ principle that the unit of protection is the class, in other words, the keywords private and protected are meant to protect against reference from outside of the class, not within. (The Annotated C++ Reference by Stroustrup, section on protected members)

Note that the program compiles when the protected keyword is replaced by public.

Alexo, I inadvertently missed the semicolon, it should be present.  Thanks for the catch.

Motaz, I was not trying to reference the protected structs from outside of the class.  The problem lies in trying to reference a protected member struct from within a class.

I would be interested to know if other C++ will produce an error compiling the code (Borland, Symantec, Linux, SunSparc...)  So far we know that MSVC 4.x and 5.x will compile the code without errors.

Thanks all for the response.
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1171001
I don't know if this is a bug in the compiler or a not however, I suggest trying this,

class T {
protected:
 typedef struct {
  int a;
 } s1;
 typedef struct {
  T::s1 b;   /// <--- this is the line I'd change
 } s2;
} ;
main ()
{
 return 1;
}

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 22

Expert Comment

by:nietod
ID: 1171002
>>I don't think the text you quoted will apply here, not so much because the code
>> didn't have any friend or static functions, but because the struct T::s2 doesn't
>> need any special access rights at all.  T::s1 was declared before
>> T::s2, and both structs are members of the same class, so in my thinking,
>> T::s2 SHOULD be able to reference T::s1.

xyu is right.  It  shouldn't.  T:s1 is private to class T.  T::s2 does not have access to T's private members.  You need to make t::s2 public OR make T:s1 (and s2) friends of T.  (that's what I would do.)


0
 

Author Comment

by:jerrydy
ID: 1171003
Nietod,

Here's a variation of the program:

class T {
protected:
 typedef int s1;
 typedef struct {
  s1 b;
 } s2;
};
main ()
{
 return 1;
}

If T::s2 does not have access to T's private (or protected) members, then this should generate the same error as when T::s1 was a class. This code compiles without errors.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171004
That doesn't surprise me.  I believe (And I definitily could be wrong) that typedef's don't have public/private/protected access.  They simply act as if they are public.  They obey class scope, but not access type.

Anyone know anything about this one way or the other?
0
 
LVL 23

Expert Comment

by:chensu
ID: 1171005
The fact that Visual C++ does not complain it surprises me more actually.

class T {
protected:
 typedef struct {
  int a;
 } s1;
 typedef struct {
  s1 b;  // you are accessing a protected member (s1) of another class (T) while this class (s2) is defined in that class (T).
 } s2;
};

The case typedef int s1 is different because int is a basic data type.
0
 
LVL 3

Accepted Solution

by:
xyu earned 200 total points
ID: 1171006
To jerrydy

>> The error violates the C++ principle that the unit of
>> protection is the class, in other words, the keywords private
>> and protected are meant to protect against reference from
>> outside of the class, not within. (The Annotated C++ Reference
>> by Stroustrup, section on protected members)

Sir... It's not philosophic question... there is draft of the standard... and the text i mentioned in my (rejected) answer is taken from there.... If You have any problem with that don't use C++ - go to Java ...

0
 
LVL 22

Expert Comment

by:nietod
ID: 1171007
The following is from the C++ Programing Language 3rd edition byy BjarneStroustrup.  Page 851.  
************************************
The members of a member class [(nested class)] have no special access to members of an enclosig class.  Similarly members of an enclosing class have no special access to members of a nested class. .....

class Outer {
   typedef int T;
   int i;
public:
   int i2;
   static int s;
   class Inner {
      int x;
      T y; // errer Outer::T is private.
   public
      void f(outer *p, in v);
};
**********************************************

That spells it out.  The code should not compile with the nested classes as protected or private (or a typedef, I was wrong on that one).  You need to make the nested classes public or use friend declarations.
0
 
LVL 3

Expert Comment

by:xyu
ID: 1171008
nietod thanks for support :)
0
 

Author Comment

by:jerrydy
ID: 1171009
Nietod,

I found the text you quoted. Now I'm convinced that you and Xyu are right.  Strangely, the last example you quoted did compile! (after adding a missing right bracket)  But typedef T to a class (per my first example), then you get the error.

Chensu, you made a comment that a typedef of int is different because it is a basic datatype. Perhaps you'd elaborate?
0
 

Author Comment

by:jerrydy
ID: 1171010
Nietod,

I found the text you quoted. Now I'm convinced that you and Xyu are right.  Strangely, the last example you quoted did compile! (after adding a missing right bracket)  But typedef T to a class (per my first example), then you get the error.

Chensu, you made a comment that a typedef of int is different because it is a basic datatype. Perhaps you'd elaborate?
0
 
LVL 23

Expert Comment

by:chensu
ID: 1171011
Actually that was a wrong guess. According to what nietod quoted, compilers should report an error regardless of the type.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now