Connecting Tech Pros Worldwide Forums | Help | Site Map

Protected Constructor

Chetan Raj
Guest
 
Posts: n/a
#1: Jul 23 '05
Hi All,

I don't understand why the following code does not compile...


#include <iostream>

using namespace std;

class A
{
protected:
A()
{
cout<<" I am A;";
x = 5;
}

int GiveX()
{
return x;
}
int x ;

};

class B : public A
{
public:
B()
{
A* p = new A();
cout<<"I am B with x = "<<GiveX()<<endl;
}


};


int main(int argc, char* argv[])
{
B b;
return 0;
}


The compiler will show the following error at line containg A* p =
new A();[color=blue][color=green]
>>[/color][/color]
'A::A' : cannot access protected member declared in class 'A'
<<
but not when I use only GiveX() function.

class B derives publicly form A. Both A() and GiveX() are protected
functions in class A.

When we can use the function GiveX(), why cannot we use the protected
constructor?

Can anyone explain this behaviour?

Thanks in advance,
Chetan Raj


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Victor Bazarov
Guest
 
Posts: n/a
#2: Jul 23 '05

re: Protected Constructor


Chetan Raj wrote:[color=blue]
> I don't understand why the following code does not compile...
>
>
> #include <iostream>
>
> using namespace std;
>
> class A
> {
> protected:
> A()
> {
> cout<<" I am A;";
> x = 5;
> }
>
> int GiveX()
> {
> return x;
> }
> int x ;
>
> };
>
> class B : public A
> {
> public:
> B()
> {
> A* p = new A();
> cout<<"I am B with x = "<<GiveX()<<endl;
> }
>
>
> };
> [...]
> When we can use the function GiveX(), why cannot we use the protected
> constructor?[/color]

Because objects are only allowed to access A's protected members for the
instances of the same type as their own. When c-tors are concerned, only
creating of the base class subobject is allowed, not a stand-alone object.

V
Maciej Pilichowski
Guest
 
Posts: n/a
#3: Jul 23 '05

re: Protected Constructor


On 26 Apr 2005 05:22:36 -0400, "Chetan Raj" <hichetu@gmail.com>
wrote:
[color=blue]
>class B derives publicly form A. Both A() and GiveX() are protected
>functions in class A.[/color]

....so you can use both as part of _current_ object /of class B/!

B::B() : A() // call A c-tor for THIS object, visible -> allowed
{
A* p = new A(); // call A c-tor for an object, not visible
}

have a nice day, bye
--
Maciej "MACiAS" Pilichowski http://bantu.fm.interia.pl/

M A R G O T --> http://www.margot.cad.pl/
automatyczny t³umacz (wczesna wersja rozwojowa) angielsko-polski
codigo
Guest
 
Posts: n/a
#4: Jul 23 '05

re: Protected Constructor



"Maciej Pilichowski" <bantu@SKASUJTOpoczta.FM> wrote in message
news:92hs61dojg5mlf3221t4kvod4nlenc7fiv@4ax.com...[color=blue]
> On 26 Apr 2005 05:22:36 -0400, "Chetan Raj" <hichetu@gmail.com>
> wrote:
>[color=green]
> >class B derives publicly form A. Both A() and GiveX() are protected
> >functions in class A.[/color]
>
> ...so you can use both as part of _current_ object /of class B/!
>
> B::B() : A() // call A c-tor for THIS object, visible -> allowed[/color]

You can't call a ctor. Constructors are not called, they are invoked. Thats
because you can't overide or redefine a base class constructor. The B class
can call, overload or overide GiveX() but it can only invoke A's ctor.
[color=blue]
> {
> A* p = new A(); // call A c-tor for an object, not visible[/color]

Which raises a thorny issue (thats the question your post has me begging to
ask...). Since pointer p ceases to exist once the constructor has finished
constructing, how do you then deallocate the instance of A at p?

The answer is you can't delete p. Thats a guarenteed memory leak.
[color=blue]
> }
>
> have a nice day, bye
> --
> Maciej "MACiAS" Pilichowski[/color]
http://bantu.fm.interia.pl/[color=blue]
>
> M A R G O T --> http://www.margot.cad.pl/
> automatyczny t³umacz (wczesna wersja rozwojowa) angielsko-polski[/color]


Maciej Pilichowski
Guest
 
Posts: n/a
#5: Jul 23 '05

re: Protected Constructor


On Tue, 26 Apr 2005 12:27:08 -0400, "codigo" <codigo@codigo.trap.com>
wrote:
[color=blue]
>You can't call a ctor. Constructors are not called, they are invoked.[/color]

Ok, language /English/ issues -- my mistake :-)
[color=blue]
>Thats
>because you can't overide or redefine a base class constructor.[/color]

Maybe it is the same as the above, but yes, I can...
[color=blue]
>The B class
>can call, overload or overide GiveX() but it can only invoke A's ctor.[/color]

....sure, but as well it doesn't have to, right? So

A::A()
{
something();
}

B::B()
{
something_completely_different();
};
[color=blue]
>Since pointer p ceases to exist once the constructor has finished
>constructing, how do you then deallocate the instance of A at p?
>The answer is you can't delete p. Thats a guarenteed memory leak.[/color]

a) this is just an example of different matter
b) you can't free any memory because this code won't compile -- that's
why

have a nice day,
bye

--
Maciej "MACiAS" Pilichowski http://bantu.fm.interia.pl/

M A R G O T --> http://www.margot.cad.pl/
automatyczny t³umacz (wczesna wersja rozwojowa) angielsko-polski
Ron Natalie
Guest
 
Posts: n/a
#6: Jul 23 '05

re: Protected Constructor


Chetan Raj wrote:
not when I use only GiveX() function.[color=blue]
>
> class B derives publicly form A. Both A() and GiveX() are protected
> functions in class A.
>
> When we can use the function GiveX(), why cannot we use the protected
> constructor?
>[/color]


Because A()'s constructor isn't accessible there. A protected member
can only be accessed by derived instances of the same object. Here
you're creating a different object in B's constructor.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

radu.chindris@gmail.com
Guest
 
Posts: n/a
#7: Jul 23 '05

re: Protected Constructor


The problem is that B doesn't inherit the constructor from A (
constructors, destructor, the = operator and friends are not
inherited).


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Allan W
Guest
 
Posts: n/a
#8: Jul 23 '05

re: Protected Constructor


Chetan Raj wrote: (edited for brevity)[color=blue]
> #include <iostream>
> using namespace std;
>
> class A {
> protected:
> A() : x(5) {}
> int GiveX() { return x; }
> int x ;
> };
>
> class B : public A {
> public:
> B() {[/color]
// This line gets error "cannot access protected member"[color=blue]
> A* p = new A();[/color]
// But this line does not:[color=blue]
> cout<<"I am B with x = "<<GiveX()<<endl;
> }
> };[/color]

I was certain this was one of Marshal Cline's FAQs, but I couldn't
find it when I searched.

Chetan, this confused me too when I first encountered it. The answer
is that just because B inherits from A does not mean that it has
friend-type access to all of the protected members. It only has
access to the protected members of the base object -- the A that's
part of the B.

Here's another example of what does not work:

class C : public A {
public:
C() {
A*p = this; // Okay
cout << GiveX(); // Okay
cout << this->GiveX(); // Also okay
cout << p->GiveX(); // No.
}
};

You cannot access protected members of A through a pointer to A.
You can only access protected members of A through a pointer to C
(or the implied this pointer). This is intentional.

You can solve your problem by making B a friend of A -- but I
suspect you already knew that.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Bo Persson
Guest
 
Posts: n/a
#9: Jul 23 '05

re: Protected Constructor



"Chetan Raj" <hichetu@gmail.com> skrev i meddelandet
news:1114430232.178343.79190@o13g2000cwo.googlegro ups.com...[color=blue]
> Hi All,
>
> I don't understand why the following code does not compile...
>
>
> #include <iostream>
>
> using namespace std;
>
> class A
> {
> protected:
> A()
> {
> cout<<" I am A;";
> x = 5;
> }
>
> int GiveX()
> {
> return x;
> }
> int x ;
>
> };
>
> class B : public A
> {
> public:
> B()
> {
> A* p = new A();
> cout<<"I am B with x = "<<GiveX()<<endl;
> }
>
>
> };
>
>
> int main(int argc, char* argv[])
> {
> B b;
> return 0;
> }
>
>
> The compiler will show the following error at line containg A* p =
> new A();[color=green][color=darkred]
>>>[/color][/color]
> 'A::A' : cannot access protected member declared in class 'A'
> <<
> but not when I use only GiveX() function.
>[/color]

The GiveX function is a part of the B object, it actually calls
this->GiveX(). It has access to this function, because it inherits it
from its base class A.

When it tries to create a new A object, that's a totally different
object to which it does not have access.


Bo Persson



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

codigo
Guest
 
Posts: n/a
#10: Jul 23 '05

re: Protected Constructor



"Chetan Raj" <hichetu@gmail.com> wrote in message
news:1114430232.178343.79190@o13g2000cwo.googlegro ups.com...[color=blue]
> Hi All,
>
> I don't understand why the following code does not compile...
>
>
> class B : public A
> {
> public:
> B()
> {
> A* p = new A();[/color]

the variable *p is *not* a member of the B class. Neither can B inherit from
an instance. One does not inherit from a variable. Since the A ctor is
protected, the above doesn't compile. The class B() ctor should look like
this:

B() : A() { cout << "B ctor invoked\n"; }

The A class found in B's initialization list *is* an inherited class (not an
instance). Instantiation of a class B variable therefore *invokes* the base
class ctor this way.

So...
B *ptr = new B();
invokes both: A's protected ctor and invokes B's ctor.

A class is not a variable (an instance). You can't inherit from an instance.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

James Kanze
Guest
 
Posts: n/a
#11: Jul 23 '05

re: Protected Constructor


Allan W wrote:[color=blue]
> Chetan Raj wrote: (edited for brevity)[/color]
[color=blue][color=green]
>>#include <iostream>
>>using namespace std;[/color][/color]
[color=blue][color=green]
>>class A {
>>protected:
>> A() : x(5) {}
>> int GiveX() { return x; }
>> int x ;
>>};[/color][/color]
[color=blue][color=green]
>>class B : public A {
>>public:
>> B() {[/color][/color]
[color=blue]
> // This line gets error "cannot access protected member"[/color]
[color=blue][color=green]
>> A* p = new A();[/color][/color]
[color=blue]
> // But this line does not:[/color]
[color=blue][color=green]
>> cout<<"I am B with x = "<<GiveX()<<endl;
>> }
>>};[/color][/color]
[color=blue]
> I was certain this was one of Marshal Cline's FAQs, but I
> couldn't find it when I searched.[/color]
[color=blue]
> Chetan, this confused me too when I first encountered it. The
> answer is that just because B inherits from A does not mean
> that it has friend-type access to all of the protected
> members. It only has access to the protected members of the
> base object -- the A that's part of the B.[/color]

Almost. You need to replace the 'the's with 'a's in the last
sentence. A derived class B can only access the protected
members of a base A in objects whose actual type is a B (or
derived from B). In his example, for example :

B* pB ;
pB->GiveX() ; // Legal.
A* pA ;
pA->GiveX() ; // Illegal.

--
James Kanze mailto: james.kanze@free.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Closed Thread