Protected Constructor

C

Chetan Raj

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();'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
 
V

Victor Bazarov

Chetan said:
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?

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
 
M

Maciej Pilichowski

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

....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
 
C

codigo

Maciej Pilichowski said:
...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

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.
{
A* p = new A(); // call A c-tor for an object, not visible

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.
 
M

Maciej Pilichowski

You can't call a ctor. Constructors are not called, they are invoked.

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

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

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

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

B::B()
{
something_completely_different();
};
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.

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
 
R

Ron Natalie

Chetan Raj wrote:
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?


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.
 
R

radu.chindris

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

Allan W

Chetan Raj wrote: (edited for brevity)
#include <iostream>
using namespace std;

class A {
protected:
A() : x(5) {}
int GiveX() { return x; }
int x ;
};

class B : public A {
public:
B() {
// This line gets error "cannot access protected member"
A* p = new A(); // But this line does not:
cout<<"I am B with x = "<<GiveX()<<endl;
}
};

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.
 
B

Bo Persson

Chetan Raj said:
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();'A::A' : cannot access protected member declared in class 'A'
<<
but not when I use only GiveX() function.

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
 
C

codigo

Chetan Raj said:
Hi All,

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


class B : public A
{
public:
B()
{
A* p = new A();

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.
 
J

James Kanze

Allan said:
Chetan Raj wrote: (edited for brevity)
// This line gets error "cannot access protected member"
// But this line does not:
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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top