PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : pure virtual???



p_mork
06.05.2007, 20:59
Hallo,

ich hab mal wieder versucht, objektorientiert zu proggen. Leider klappt es nicht so wie es sollte. Beim folgendem Code bekomme ich 'ne Fehlermeldung:
class a
{
public:
virtual void mach()=0;
};

class b:public a
{
public:
void mach()
{
}
};

int main()
{
b x;
x.mach();
}

Und hier das Output vom Compiler:


> "make.exe" all

-------- begin --------
avr-gcc (GCC) 3.4.6
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Compiling C++: main.cpp
avr-gcc -c -mmcu=atmega32 -I. -x c++ -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -fno-exceptions -Wall -Wa,-adhlns=obj/main.lst -MD -MP -MF .dep/main.o.d main.cpp -o obj/main.o
main.cpp:37: warning: alignment of 'b::_ZTV1b' is greater than maximum object file alignment. Using 1
main.cpp:31: warning: alignment of 'a::_ZTV1a' is greater than maximum object file alignment. Using 1

Linking: testpp.elf
avr-gcc -mmcu=atmega32 -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.o -std=gnu99 -Wundef -MD -MP -MF .dep/testpp.elf.d obj/main.o --output testpp.elf -Wl,-Map=testpp.map,--cref -lm
obj/main.o:(.data+0xa): undefined reference to `__cxa_pure_virtual'
make.exe: *** [testpp.elf] Error 1

> Process Exit Code: 2
> Time Taken: 00:00

Weiss jemand, was diesmal nicht klappt???

MfG Mark

p_mork
07.05.2007, 15:24
Da mir darauf anscheined keiner eine Antwort geben gann stelle ich mal eine andere Frage.
Was beduetet die Warnung "ignment of 'a::_ZTV1a' is greater than maximum object file alignment. Using 1"???
Diese tritt auch dann auf, wenn ich die Methode 'mach' in der Klasse 'a' nicht pure virtual mache sondern auch einen Funktionsblock dahinter erstelle. Wo liegt da das Problem? Kann AVR-GCC mit 'virtual' nichts anfangen???

](*,) ](*,) ](*,)

MfG Mark

leviathan
07.05.2007, 16:17
Hi,

für C++ musst du den 'avr-g++' verwenden; dann sollte es klappen.

-Tim

p_mork
07.05.2007, 21:02
Hallo,
das Problem ist dank Mikrocontroller.net gelöst worden. Da hat nur eine Funktion __cxa_pure_virtual() gefehlt, die ausgelöst werden soll, wenn durch einen Fehler im Programm eine pure vertual-Methode ausgeführt wird. Sie sollte in der std-Lib von C++ vorhanden sein, aber für den AVR gibts ja keine^^. Trotzem danke für den Versuch.

MfG Mark

ehenkes
06.08.2007, 21:55
Ich erhalte auch diese Fehlermeldung.
Kann man wirklich keine abstrakten Basisklassen verwenden?



#ifndef STATE_H
#define STATE_H

class Bot;

class State // abstrakte Klasse
{
public:
virtual ~State(){}
virtual void Execute(Bot*) = 0;
};

#endif

p_mork
07.08.2007, 10:41
Hallo ehenkes,

wie gesagt, da fehlt die Funktion __cxa_pure_virtual(), die immer dann angespungen wird, wenn eine rein virtuelle Methode trotzdem ausgeführt wird, z.b. durch einen dynamic_cast<>. Du kannst die Funktion aber problemlos selbst schreiben. ein Bsp. dafür ist das hier:
/*!
* \brief Pure-virtual workaround.
*
* The avr-libc does not support a default implementation for handling
* possible pure-virtual calls. This is a short and empty workaround for this.
*/
extern "C" {
void __cxa_pure_virtual()
{
// put error handling here
}
}

Siehe auch http://www.mikrocontroller.net/topic/68813#new

MfG Mark

ogni42
07.08.2007, 15:09
Es sollte reichen dem Compiler mitzuteilen, dass er keine exceptions verwenden soll: -fno_exceptions (wenn ich mich richtig erinnere).

ehenkes
07.08.2007, 20:11
@ogni42:
1) -fno-exceptions (nicht -fno_exceptions)
2) nein reicht leider nicht, Linker-Fehlermeldung kommt trotzdem.

@p_mork:
Genau das ist die Lösung, damit das Programm läuft.

ogni42
07.08.2007, 21:38
Stimmt, Ihr habt recht.

ehenkes
07.08.2007, 21:43
Keine Ahnung, ob dies mit der methodik noch einen Unterschied macht:

virtual void Execute(Bot*) = 0; // pure virtual

virtual void Execute(Bot*){}; // virtual

ogni42
07.08.2007, 21:54
Letzteres geht auch, ohne dass man die zusätzliche Funktion definiert. Ersteres ist der bessere Weg, wenn man sauber Schnittstellen definieren will (ähnlich "interface" in Java), da nur so verhindert wird, dass von dieser Klasse Objekte instantiiert werden können.

ehenkes
07.08.2007, 22:06
In welcher Bibliothek befindet sich eigentlich __cxa_pure_virtual? Ich habe schon libstdc++.a und libsupc++.a aus anderen IDEs "geklaut" und gelinkt, allerdings ohne Erfolg.

p_mork
08.08.2007, 11:24
Hallo ehenkes,

__cxa_pure_virtual() befindet sicht normaleweise in der libsupc++.a. Aus welchen IDEs genau hast Du sie genommen?

MfG Mark

ehenkes
08.08.2007, 20:19
Das war Dev-C++ 4.9.9.0, vielleicht schon zu alt.