By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,053 Members | 1,223 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,053 IT Pros & Developers. It's quick & easy.

Multiple inheritance and access specifiers issue.

P: n/a
I have a following piece of code. The code was compiled using g++

class A
{
public :
virtual void fn() = 0;
};

class B: virtual private A
{
public:
void fn() { cout << "I m here\n"; }
};

class C : public virtual A
{
};

class D : private B, virtual public C
{
};

int main()
{
D *mod1 = new D;
A *mod2 = mod1;
mod2->fn();

/* The following commented code does not compile */

/*
D *dObj = new D;
dObj->fn();
*/
return 0;
}

In this code how is the function fn() accessible to mod2 given that
class D is privately inheriting the implemetation of fn() from B.
Should it not be that, since implementation of fn() is privately
inherited from B the compiler should give B::fn() not accessible error
?

When the commented code is compiled, the compiler gives the error. This
is expected.....

So, how in the first case the resolution of a function call being done ?

Jan 11 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a

Tapeesh wrote:
I have a following piece of code. The code was compiled using g++

class A
{
public :
virtual void fn() = 0;
};

class B: virtual private A
{
public:
void fn() { cout << "I m here\n"; }
};

class C : public virtual A
{
};

class D : private B, virtual public C
{
};

int main()
{
D *mod1 = new D;
A *mod2 = mod1;
mod2->fn(); In this case the mod2 is of type A*, where in which the fn() is defined
in the public section.
/* The following commented code does not compile */

/*
D *dObj = new D;
dObj->fn(); In this case the dObj is of type D* where the fn() is in the private
section. Because the class B derived private. */
return 0;
}

In this code how is the function fn() accessible to mod2 given that
class D is privately inheriting the implemetation of fn() from B.
Should it not be that, since implementation of fn() is privately
inherited from B the compiler should give B::fn() not accessible error
?

When the commented code is compiled, the compiler gives the error. This
is expected.....

So, how in the first case the resolution of a function call being done ?


Virtual Fuctions assume the access level of the
object/pointer/reference through which they are called.

Jan 11 '06 #2

P: n/a
Tapeesh wrote:
class A { public : virtual void fn() = 0;};
class B: virtual private A { public: void fn() { cout << "I m here\n"; } };
class C : public virtual A { };
class D : private B, virtual public C { }; int main()
{
D *mod1 = new D;
A *mod2 = mod1;
mod2->fn();
mod2 is A* and fn() is public in class A. No compiler error.
/* The following commented code does not compile */

/*
D *dObj = new D;
dObj->fn();
dObj is D* and 'fn' is private in B* and hence inaccessible for D*.
*/
return 0;
}

In this code how is the function fn() accessible to mod2 given that
class D is privately inheriting the implemetation of fn() from B.
Should it not be that, since implementation of fn() is privately
inherited from B the compiler should give B::fn() not accessible error
?


Note that type checking is done at compile time, so when you say
mod2->fn(), the compiler has no way to understand that mod2 is A* but
the actual object pointed is D.

Jan 11 '06 #3

P: n/a
Neelesh Bodas wrote:
Tapeesh wrote:
class A { public : virtual void fn() = 0;};
class B: virtual private A { public: void fn() { cout << "I m here\n"; } };
class C : public virtual A { };
class D : private B, virtual public C { };

int main()
{
D *mod1 = new D;
A *mod2 = mod1;
mod2->fn();


mod2 is A* and fn() is public in class A. No compiler error.
/* The following commented code does not compile */

/*
D *dObj = new D;
dObj->fn();


dObj is D* and 'fn' is private in B* and hence inaccessible for D*.
*/
return 0;
}

In this code how is the function fn() accessible to mod2 given that
class D is privately inheriting the implemetation of fn() from B.
Should it not be that, since implementation of fn() is privately
inherited from B the compiler should give B::fn() not accessible error
?


Note that type checking is done at compile time, so when you say
mod2->fn(), the compiler has no way to understand that mod2 is A* but
the actual object pointed is D.


This is fine that the compiler has no way to understand that mod2
is actually pointing to object of D.

But when this code is executed, how is a privately inherited
function accessible ? Because dynamic binding will resolve that mod2 is
actually of type D and then fn() is being called which is a private
function of D. So, at execution time there should be some error but the
privately inherited definition of fn() is getting executed. Or

1.) Is it that access specifiers are important only at compile time and
have no meaning during execution?

2.) This type of inheritance is providing a way for accessing private
members of a class?

Jan 12 '06 #4

P: n/a
Tapeesh wrote:
Neelesh Bodas wrote:
Tapeesh wrote:
class A { public : virtual void fn() = 0;};
class B: virtual private A { public: void fn() { cout << "I m here\n"; } };
class C : public virtual A { };
class D : private B, virtual public C { };
int main()
{
D *mod1 = new D;
A *mod2 = mod1;
mod2->fn();
return 0;
}

This is fine that the compiler has no way to understand that mod2
is actually pointing to object of D.
But when this code is executed, how is a privately inherited
function accessible ?
Execution knows nothing about access specifiers, the actual assembly
code simply goes at the proper offset within the class.
Because dynamic binding will resolve that mod2 is actually of type D and then fn() is

No. Dynamic binding doesnot resolve the "types" - type checking is
always done at compile time. What dynamic binding means is that the
name-value association (aka, answer to the question "Which definition
does this name correspond to") is delayed till run time.

Also note that the term "dynamic binding" has nothing to do with the
term "Dynamic type checking" - these two are different concepts.

being called which is a private
function of D. So, at execution time there should be some error but the
privately inherited definition of fn() is getting executed. Or

Access specifiers, Types, function prototypes, existence of a "class"
and a friend, and most of the other langauge constructs are known only
to the compiler.
2.) This type of inheritance is providing a way for accessing private
members of a class?


Not really - fn() was public in B . Just make fn() private in B and
don't be surprised if you get linker errors.

Jan 12 '06 #5

P: n/a

Neelesh Bodas wrote:
Tapeesh wrote:
Neelesh Bodas wrote:
Tapeesh wrote:

> class A { public : virtual void fn() = 0;};
> class B: virtual private A { public: void fn() { cout << "I m here\n"; } };
> class C : public virtual A { };
> class D : private B, virtual public C { };

> int main()
> {
> D *mod1 = new D;
> A *mod2 = mod1;
> mod2->fn();
> return 0;
> }
>

This is fine that the compiler has no way to understand that mod2
is actually pointing to object of D.

But when this code is executed, how is a privately inherited
function accessible ?


Execution knows nothing about access specifiers, the actual assembly
code simply goes at the proper offset within the class.
Because dynamic binding will resolve that mod2 is actually of type D and then fn() is

No. Dynamic binding doesnot resolve the "types" - type checking is
always done at compile time. What dynamic binding means is that the
name-value association (aka, answer to the question "Which definition
does this name correspond to") is delayed till run time.

Also note that the term "dynamic binding" has nothing to do with the
term "Dynamic type checking" - these two are different concepts.

being called which is a private
function of D. So, at execution time there should be some error but the
privately inherited definition of fn() is getting executed. Or


Access specifiers, Types, function prototypes, existence of a "class"
and a friend, and most of the other langauge constructs are known only
to the compiler.
2.) This type of inheritance is providing a way for accessing private
members of a class?


Not really - fn() was public in B . Just make fn() private in B and
don't be surprised if you get linker errors.


I tried with fn() private in class B. It has no effect. There is no
compiler error (just a warning that B has all its members functions
private) or any run time error. But making fn() private in A gives a
compile time error, which is as expected.
So, this means that
This type of inheritance is providing a way for accessing private
members of a class?

Jan 12 '06 #6

P: n/a

Tapeesh wrote:

Not really - fn() was public in B . Just make fn() private in B and
don't be surprised if you get linker errors.
I tried with fn() private in class B. It has no effect. There is no
compiler error (just a warning


I see. Yeah it will work since B-subobject of D has fn() defined. I had
changed the code a bit and didnot remember that, hence got linking
errors.
So, this means that
This type of inheritance is providing a way for accessing private
members of a class?


No idea. Somebody else, please comment on this.

Jan 12 '06 #7

P: n/a
No idea. Somebody else, please comment on this.


Luck? The private fn()-method of B is probably at the right place
in the vtable of the object.

Does it still work if you define
class D : virtual public C, private B
{

};
?

rs

Jan 12 '06 #8

P: n/a

Neelesh Bodas wrote:
Tapeesh wrote:

Not really - fn() was public in B . Just make fn() private in B and
don't be surprised if you get linker errors.


I tried with fn() private in class B. It has no effect. There is no
compiler error (just a warning


I see. Yeah it will work since B-subobject of D has fn() defined. I had
changed the code a bit and didnot remember that, hence got linking
errors.
So, this means that
This type of inheritance is providing a way for accessing private
members of a class?


No idea. Somebody else, please comment on this.


Hi,
IMO, I believe this is more to conceptual issue rather than technical
issue.
If your grandaddy says, his motorcycle should be given TO ANYONE, and
then your father keep it as his own, without giving to anyone, but your
mother disagree, and still give it TO ANYONE. Then when your time
comes, you keep the motorcycle (you believe the motorcycle should be
give & not give), but then someone ask your grandfather (not you) for
his motorcycle. Guess, what your grandpa says? GIVE IT TO THEM or i
take it back! why? because grandpa already says PUBLIC. Got it?? :-)

Maybe this can be seen as alternative (back door) to 'private'd method.
But i rather believe this is natural, because originally, the function
already defined as public. If the fn() defined as private in A, that's
another thing.

Jan 13 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.