Toon posts:

[C++] Inheritance / static_cast probleem

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben momenteel bezig met wat oude c++ projecten weer wat nieuw leven in blazen. Het grootste obstakel is dat de meeste compilers behoorlijk wat stricter zijn geworden.

De code ( beetje simplified weer gegeven vanwege de spaghetti vormen van de originele code):
C++:
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
class Derived1;
class Base {
    Base(const Base &);
    Base & operator=(const Base &);
protected:
    Base() {}
    ~Base() {}

    Derived1 * next; 

    void test();

    friend class Derived1;
    };

class Derived1 :  public Base {
    Derived1(const Derived1 &);
    Derived1 & operator=(const Derived1 &);
protected:
    Derived1() {}
    ~Derived1() {}

    friend class Base;
    };

class OtherBase {
public:
    void call_me() {}
    };

class Derived2 : public OtherBase, private Derived1 {
public:
    Derived2() {}
    ~Derived2() {}
    };

void Base::test() {
    /*dit neemt aan dat er altijd Derived2 type objecten worden opgeslagen in next */
    Derived1 * d1 = next; 
    Derived2 * d2 = static_cast<Derived2*>(d1);
    d2->call_me();
    }


De error:

(icc 9.1) error #1556: conversion from inaccessible base class "Derived1" is not allowed
Derived2 * d2 = static_cast<Derived2*>(d1);

(gcc) error: ‘Derived1’ is an inaccessible base of ‘Derived2’

VC2005/icc 9.0 klaagden er niet over.

Ik ben geen C++ guru en gegeven het feit dat ik deze code niet heb geschreven vraag ik mij af wat ik nou het beste kan doen om het werkend te krijgen. Als ik Derived2 protected of public inherit van Derived1 dan werkt (als in geen compiler errors) weer wel. Maar "klopt" het idee achter de code dan nog wel?

[ Voor 0% gewijzigd door Verwijderd op 27-09-2006 22:03 . Reden: oops... protected werkt niet nee... ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Protected inheritance werkt wel? Vreemd, dat hoort namelijk ook niet. Het is natuurlijk simpel: alleen scopes die toegang hebben tot de private delen van Derived2 (dus Derived2 zelf en eventuele nested classes en friends) kunnen zien dat Derived2 van Derived1 inherit. Base heeft geen toegang tot Derived2 dus die kan de cast ook niet uitvoeren.

Je zou Base::test een friend kunnen maken, of heel Base, of idd de inheritance veranderen. Je app zal niet ineens rare dingen gaan doen, of het idee achter dit ontwerp dan nog stand houdt is eigenlijk niets over te zeggen zonder dat idee te kennen :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
.oisyn schreef op woensdag 27 september 2006 @ 21:59:
Je zou Base::test een friend kunnen maken, of heel Base, of idd de inheritance veranderen. Je app zal niet ineens rare dingen gaan doen, of het idee achter dit ontwerp dan nog stand houdt is eigenlijk niets over te zeggen zonder dat idee te kennen :)
Ah ok. Ik snap hem nu. Bedankt. En inderdaad die protected inheritance werkt niet nee. Het idee achter dit ontwerp wil ik eigenlijk gewoon niet weten :P

Verwijderd

Topicstarter
.oisyn schreef op woensdag 27 september 2006 @ 21:59:
Je zou Base::test een friend kunnen maken, of heel Base, of idd de inheritance veranderen. Je app zal niet ineens rare dingen gaan doen, of het idee achter dit ontwerp dan nog stand houdt is eigenlijk niets over te zeggen zonder dat idee te kennen :)
Ok als ik Base::test friend maak van Derived2 dmv

C++:
1
friend void Base::test(); 


Dan werkt dat voor de intel compiler, maar niet voor gcc :)

error: ‘void Base::test()’ is protected
test.cpp:39: error: within this context

Dat zou toch moeten werken omdat Derived2 een derived class van Base is (en dus toegang zou moeten hebben tot protected members). Alhoewel misschien zit de private inheritance de zaak te verpesten? :?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nee, die private inheritance maakts uit; dat is om voor de buitenwereld te verbergen dat Derived2 van Derived1 inherit. Derived2 weet zelf natuurlijk dondersgoed dat het een Derived1 -en dus een Base- is, en hij zou daarom toegang moeten hebben tot Base::test

Welke gcc versie is dat?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
.oisyn schreef op donderdag 28 september 2006 @ 01:33:
Nee, die private inheritance maakts uit; dat is om voor de buitenwereld te verbergen dat Derived2 van Derived1 inherit. Derived2 weet zelf natuurlijk dondersgoed dat het een Derived1 -en dus een Base- is, en hij zou daarom toegang moeten hebben tot Base::test

Welke gcc versie is dat?
gcc 4.1.1

Dit werkt niet met gcc:

C++:
1
2
3
4
5
6
7
class Derived2 : public OtherBase, private Derived1 {
public:
    Derived2() {}
    ~Derived2() {}

    friend void Base::test();
    }; 


Dit werkt wel:

C++:
1
2
3
4
5
6
7
class Derived2 : public OtherBase, private Derived1 {
public:
    Derived2() {}
    ~Derived2() {}

    friend class Base;
    }; 

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 18:09
Ik snap eerlijk gezgd ook hier weer niet waarom de base class een ref zou moeten hebben naar een child class type. Volgend mij zit er ook hier een fout in het (inheritance) ontwerp.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
De "friend void Base::test;" oplossing werkt ook voor Comeau C++. Zou dit een bug in gcc kunnen zijn :*)

Verwijderd

Topicstarter
farlane schreef op donderdag 28 september 2006 @ 08:53:
Ik snap eerlijk gezgd ook hier weer niet waarom de base class een ref zou moeten hebben naar een child class type. Volgend mij zit er ook hier een fout in het (inheritance) ontwerp.
Ja die snap ik zelf ook niet helemaal. Vooral omdat in de echte code Derived1 een member "const Base * prev;" heeft 8)7 .
Pagina: 1