upcast with protected base unaccessible

Pages: 12
I'm playing with dynamic_cast<>() to learn basically and I have been doing upcast that in fact are the same than an simple assignation...but the type of the destiny type is protected to the pointer or reference to be casted it's not possible to do it( I guess when it is private it happens too).

My question is the next: why can't it be done? is it because the constructor of the base class are protected but as long as I know members data of a base class are accessible to the derived class.....any light on this please??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  
#include <stdio.h>
#include <iostream>


class Storable{
	
	void virtual write();
	
};

class Component: public virtual Storable{
	void write();
};

class Receiver: public Component{
	void write();
};

class Transmitter: public Component{
	void write();
};

class Radio: protected Receiver, public Transmitter{
	void write();
};




int main(){
	Radio* ptrRadio;
	Receiver* ptrReceiver;
	ptrReceiver = ptrRadio;
	ptrReceiver = dynamic_cast<Receiver*>(ptrRadio);
}



I know that a cast and an assignation are the same while it's an upcast...but the matter is the protected base...thanks!!!
why can't it be done?
Because it is protected. Only class itself and it its descendans "knows" that it is inherited from Receiver. For everyone else it is "secret".

Private/protected inheritance is used when you want to inherit from something (usually implementation inheritance), but does not want other code to threat it as is private base.
yes, but how I see it, the source is ptrRadio which is an object of Radio class and it's a class derived from Receiver...so it knows Receiver...I could understand that being a pointer from Receiver casting to a Radio...because Receiver doesn't know about Radio....sure is the other way around but I can't find the logic....
I have got it....basically I was thinking that in the dynamic_cast<type>(source) like the source was the one which had to know the relation between them......but not, which must know is the type to be converted...then downcast operations will never have that trouble...but upcast operations can have that trouble since always is a cast from a derived class to a base class so if the base inherited is protected or pirvate it won't have access and it will not know because it is a base not a derived class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


class Receiver: public Component{
	void write();
};

class Transmitter: public Component{
	void write();
};

class Radio: protected Receiver, public Transmitter{
	void write();
};

	ptrRadio = ptrReceiver;		
	
        ptrRadio = dynamic_cast<Radio*> (ptrReceiver);	


The first assignation doesn't work because it is an illegal assingation ( a pointer to a derived can't hold a pointer to a base, it needs a casting) but the compiles still shows me Receiver is a inaccessible base class of Radio....I don't know why It does that, it's just an information???
Look at your cast. Is it outside of Radio class or its descendants? If so, delete everything marked private and protected from Radio class. This is what visible from this point.
Your cast gives you an error, because everything no-public is not accessible outside of class.
This is the entire ourpose of private and protected inheritance: to hide inheritance relationship from outside and forbid convertions. Non-public inheritance tells you: this is not an is-a relationship, so pointer casting is wrong. Please give me an error if somebody will try that.
ok, then dynamic_cast when It's a downcast can deal with that...but when It's a normal assignation( that in fact is cast) It can't deal fot two reasons in this case...1ยบ It's an invalid conversion and It's protected....

But I still doubt , I understand that the the illegal conversion dynamic_cast can deal with that...but that It can deal with the protection surprise me...
Consider this:
1
2
3
4
5
6
7
class Receiver: public Component
{};
class Transmitter: public Component
{};
class Radio:  public Transmitter
{};
ptrRadio = dynamic_cast<Radio*> (ptrReceiver);
This is how class is seen fro outside. Do you understand now why it can
not work?
yes, because Radio doesn't know anything about Receiver since It's protected nevertheless is hidden for it.....but that is applicable to a ptrRadio = ptrReceiver; not to ptrRadio = dynamic_cast<Radio*> (ptrReceiver); my compiler is not given me any problem with that cast....

I added you the whole code in case something else matters...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <iostream>

using namespace std;

class Storable{
	
	void virtual write();
	
};

class Component: public Storable{
	void write();
};

class Receiver: public virtual Component{
	void  write();
};

class Transmitter: public virtual Component{
	void write();
};

class Radio: protected Receiver, public Transmitter{
	void write();
};

int main(){
	
	Radio* ptrRadio;
	Receiver* ptrReceiver;
	Transmitter* ptrTransmitter;
	//ptrRadio = ptrReceiver;
	ptrRadio = dynamic_cast<Radio*> (ptrReceiver);	
	
}	

You can try to downcast through non-public inheritance, but the cast will not work. It is not a compile-time error as dynamic cast does all checking in runtime.
ok I see what you mean, it doesn't give an error becasue it's checked in runtime, so I can expect a nullpointer in there...ok thanks...
so I can expect a nullpointer in there
Right now you can expect a crash, as ptrReceiver does not point to anywhere.
other question related....create an object from a virtual class is illegal and maybe doesn't make sense??
Apparently I can't create any object...even if they don't have data members I would be able to create object because the must provides default constructors...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40


#include <stdio.h>
#include <iostream>

using namespace std;

class Storable{
	
	void virtual write();
	
};

class Component: virtual Storable{
	void write();
};

class Receiver: public virtual Component{
	void  write();
};

class Transmitter: public virtual Component{
	void write();
};

class Radio: public Receiver, public Transmitter{
	void write();
};

int main(){
	
	//Radio object;
	//Transmitter object1;
	//Receiver object2;
	//Component object3;
		Storable object4;





do I have to define always the constructors and destructors to create object....
Apparently I can't create any object...even if they don't have data members I would be able to create object because the must provides default constructors...
YOu cannot create objects because you never fulfilled your promise of implementing all those write functions

Here is minimal example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

class Storable
{ virtual write(){} };

class Component: public Storable
{};
class Receiver: public virtual Component
{};
class Transmitter: public virtual Component
{};

class Radio: protected Receiver, public Transmitter
{
    public: Receiver* get() { return this; }
};

int main(){
    Radio* ptrRadio;
    Receiver* ptrReceiver = (new Radio)->get();
    std::cout << (ptrRadio = dynamic_cast<Radio*> (ptrReceiver));
}
I see, but apparently I cloud create objects when I declared the like this ................................ . Radio object()
and in this example I can create objects and I didn't fullfill the write beside the read and I can create objects.....but I the base is pure virtual and I have some data members...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// pointers to base class
#include <iostream>
#include <string>
using namespace std;

class Storable{
public:
	
	virtual void read() =  0;
	virtual void write() = 0;
	virtual ~Storable() {
		
	}
};

class Component: public Storable{
	 void write(){};
	 void read(){};
};

class Transmitter: public Component{
public:
	void read(){
		
	}
	void write(){
		
	}
	~Transmitter(){
	}
	Transmitter(int a):T(a){}
protected:
	int T;
};

class Receiver: public Component{
public:
	void read(){
		
	}
	void write(){
		
	}
	~Receiver(){
  }
	Receiver(int b):R(b){}
protected:
	int R;

};

class Radio: public Transmitter, public Receiver{
public:
	void read(){
		
	}
	void write(){
	
		
	}
	~Radio(){
	}
	Radio(int a,int b):Transmitter(a),Receiver(b){}
	
};

int main(){

Component object;
Radio test(4,5);
Storable* ptr;
ptr = &(Receiver&)test;
ptr->write();
}


and I didn't fullfill the write beside the read
You did. All functions are either given definition or declared as pure virtual/not requiring a definition
ok, I get it, the brackets have code or no the mean definition.......
I have done this....what I do is through a pointer base I pass a pointer to a derived class pointing to an object of its class...the dynamic_cast expected is correct....but the function is made to let me know if I sent a a pointer pointing to other class different from the one I'm casting...I was expecting the second part of the if else statment was executed....can you give any explanation ?????

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

#include <iostream>

class Storable
{ virtual void write(){}; };

class Component: public virtual Storable
{};
class Receiver: public  Component
{
	
	public: Component* get_Receiver(){return this;}
	
	};
class Transmitter: public Component
{
	public: Component* get_Transmitter(){return this;}
	};

class Radio: public Receiver, public Transmitter
{
    public: Receiver* get() { return this; }
};


void h2(Storable* ps){
	if(Component* pc = dynamic_cast<Component*>(ps)){
		std::cout<<"We have a component"<<std::endl;
	}
	else{
		std::cout<<"we dont have a component"<<std::endl;
	}
}


int main(){
    Radio* ptrRadio;
    Receiver* ptrReceiver = (new Radio)->get();
    std::cout << (ptrRadio = dynamic_cast<Radio*> (ptrReceiver));
	Transmitter *ptrTransmitter;
	Component* ptrComponent =(new Transmitter)->get_Transmitter();
	std::cout<<(ptrTransmitter = dynamic_cast<Transmitter*>(ptrComponent));
	Storable* ptrStorable;
	std::cout<<(ptrStorable = dynamic_cast<Storable*>(ptrComponent));
	/////In this part I send an object through a pointer with the same class, as function argument which is expecting super class pointer
	Component* objptr;
	Component obj2;
	objptr = &obj2;
	h2(objptr);
	//////
	///Here the same but with other object so I was expecting the casting wasnt successful
	Component* ptrComponent2;
	Transmitter objTransmitter;
	ptrComponent2 = &objTransmitter;
	h2(ptrComponent2);
}
Pages: 12