Come può una classe base soddisfare la definizione di funzione virtuale pura di un genitore utilizzando la funzione di un altro genitore

StackOverflow https://stackoverflow.com/questions/3721375

Domanda

Io sono l'estensione di un progetto esistente C ++. Ho una classe di base che deriva da due classi genitore. Uno dei genitori ha una funzione virtuale pura. Voglio che funzione virtuale pura per essere definito da una funzione implementata nel l'altro genitore.

Quindi, voglio un altro genitore per soddisfare l'obbligo della classe base per definire la funzione virtuale pura di un genitore. Ho provato due approcci, entrambi hanno portare a errori di compilazione.
Tutte le idee?

Ecco un programma C ++ che dimostra la mia prima idea, sperando che il compilatore sarebbe solo usare la definizione di base2 di vfunc().

// This is my first approach, hoping the parent base2 of derived would satisfy the need to define
// base1's pure virtual vfunc.

class base1 {
public:
 virtual int vfunc() = 0;
};

class base2 {
public:
 int vfunc() { return 0;} //defined
};

class derived : public base1, public base2 {
public:
 //empty
};

int main()
{
 derived d;
 base1 & b1 = d;
 int result = b1.vfunc();
 return result;
}

Le relazioni compilatore che derived è ancora una classe astratta:

$ gcc a.cc 
a.cc: In function ‘int main()’:
a.cc:26: error: cannot declare variable ‘d’ to be of abstract type ‘derived’
a.cc:18: note:   because the following virtual functions are pure within ‘derived’:
a.cc:7: note:  virtual int base1::vfunc()

Ecco il mio secondo tentativo:

// This is my second attempt, defining a vfunc in the derived class that calls the other parent.

class base1 {
public:
 virtual int vfunc() = 0;
};

class base2 {
public:
 int vfunc() { return 0; } // defined
};

class derived : public base1, public base2 {
public:
 int vfunc() { return base2::vfunc(); } // call the other parent's vfunc
};

int main()
{
 derived d;
 base1 & b1 = d;
 int result = b1.vfunc();
 return result;
} 

Io in realtà previsto questo per farlo per me, ma invece il linker mi sta dando un po 'di errori vtable che non capisco: (Mac OS 10.6, gcc 4.2.1)

$ gcc inheritance_tester.cc 
Undefined symbols:
  "vtable for __cxxabiv1::__vmi_class_type_info", referenced from:
      typeinfo for derivedin ccmeHq8C.o
  "___cxa_pure_virtual", referenced from:
      vtable for base1in ccmeHq8C.o
  "___gxx_personality_v0", referenced from:
      _main in ccmeHq8C.o
      base2::vfunc()     in ccmeHq8C.o
      derived::vfunc()     in ccmeHq8C.o
      base1::base1() in ccmeHq8C.o
      base2::base2() in ccmeHq8C.o
      derived::derived()in ccmeHq8C.o
      CIE in ccmeHq8C.o
  "vtable for __cxxabiv1::__class_type_info", referenced from:
      typeinfo for base1in ccmeHq8C.o
      typeinfo for base2in ccmeHq8C.o
ld: symbol(s) not found
È stato utile?

Soluzione

La seconda parte del codice è bene, non sei solo compilarlo correttamente. È necessario compilare con g ++, non gcc. Quando si compila con g ++, si collega automaticamente nelle librerie di runtime C ++; quando si compila con gcc, non è così. È inoltre possibile aggiungere manualmente da soli:

# Option 1: compile with g++
g++ inheritance_tester.cc

# Option 2: compile with gcc and link with the C++ standard libraries
gcc inheritancet_test.cc -lstdc++

Altri suggerimenti

È necessario eseguire l'override vfunc da base1. Si può fare nel seguente modo:

class derived : public base1, public base2 {
public:
 using base1::vfunc;
 int vfunc() { return base2::vfunc(); } // call the other parent's vfunc
};

Questa versione modificata del derived ha lavorato per me su Visual C ++. Implicazioni per me è che si deve disambiguare le due vfunc()s ereditate in modo esplicito.

class base1 {
public:
    virtual int vfunc() = 0;
};

class base2 {
public:
    int vfunc() { return 0;} //defined
};

class derived : public base1, public base2 {
public:
    int base1::vfunc() { return base2::vfunc(); } // call the other parent's vfunc
};

int main()
{
    derived d;
    base1 & b1 = d;
    int result = b1.vfunc();
    return result;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top