Problem z dziedziczeniem w Qt 5.1

0

Witam, piszę program wykorzystujący m. in. 3 klasy: pionek, kółko i krzyżyk. Klasy kółko i krzyżyk dziedziczą z klasy pionek. Pojawiają się 2 błędy:

  • krzyzyk.obj:-1: błąd unresolved external symbol "public: __thiscall pionek::pionek(void)" (??0pionek@@QAE@XZ) referenced in function "public: __thiscall krzyzyk::krzyzyk(void)" (??0krzyzyk@@QAE@XZ)
  • kolko.obj:-1: błąd unresolved external symbol "public: __thiscall pionek::pionek(void)" (??0pionek@@QAE@XZ)

Podejrzewam, że problem musi być z dziedziczeniem, bo przerzucam wszystkie funkcje z klasy bazowej do klas pochodnych, problem znika.

pionek.h

#ifndef PIONEK_H
#define PIONEK_H

class pionek
{

public:
    explicit pionek();
    virtual void Rysuj()=0;
    void UstawWspolrzedne(float _x, float _y);

protected:
    float x;
    float y;

};

#endif // PIONEK_H

pionek.cpp

#include "pionek.h"

pionek::pionek()
{

}

void pionek::UstawWspolrzedne(float _x, float _y)
{
    x=_x;
    y=_y;
}

kolko.h

#ifndef KOLKO_H
#define KOLKO_H

#include <QGLWidget>
#include "pionek.h"
class kolko: public pionek
{
public:

    explicit kolko();
    virtual void Rysuj();
    void UstawWspolrzedne(float _x, float _y);
signals:
    
public slots:

};

#endif // KOLKO_H

kolko.cpp

#include "kolko.h"

kolko::kolko()
{

}

void kolko::Rysuj()
{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //czyszczenie kolorem t�a
        glLoadIdentity();
        glTranslatef(x,y,0.0);

        glColor3f(0.2471f,0.2824f,0.8f);
        glBegin(GL_LINE_LOOP);
        //
        for (int angle=0; angle<365; angle=angle+5)
        {
        float angle_radians = angle * (float)3.14159 / (float)180;
        float _x = 0.4 * (float)cos(angle_radians);
        float _y = 0.4 * (float)sin(angle_radians);
        glVertex3f(_x,_y,0);
        }
        glEnd();
}

krzyzyk.h

#ifndef KRZYZYK_H
#define KRZYZYK_H

#include <QObject>
#include <QtOpenGL/QGLWidget>
#include "pionek.h"
class krzyzyk: public pionek
{
public:

    explicit krzyzyk();
    virtual void Rysuj();
    void UstawWspolrzedne(float _x, float _y);
signals:
    
public slots:

};

#endif // KRZYZYK_H

krzyzyk.cpp

#include "krzyzyk.h"

krzyzyk::krzyzyk()
{

}

void krzyzyk::Rysuj()
{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //czyszczenie kolorem t�a
        glLoadIdentity();
        glTranslatef(x,y,0.0);

        glBegin(GL_LINES);
        glColor3f(0.9294f,0.1098f,0.1412f);
        glVertex2f(-0.4f,0.4f);
        glVertex2f(0.4f,-0.4f);
        glEnd();
        glBegin(GL_LINES);
        glVertex2f(0.4f,0.4f);
        glVertex2f(-0.4f,-0.4f);
        glEnd();

}

Będę wdzięczny za sugestie i wskazówki.

3

Klasy: Pionek, Kolko i Krzyzyk to jest przedobrzenie z obiektowością. Wystarczy zwykła tablica z wartościami enum-ami.

Co do samego problemu, kod jest ok. Albo schrzaniłeś plik pro i brakuje dodania pliku źródłowego, albo cache kompilatora się schrzanił (zdarza się) i musisz zrobić, make clean (jeśli używasz lini poleceń), albo prawy przycisk myszy na projekcie i "Wyczyść projekt" ("Clean Project"), potem normalnie zbudować.

0

Dziękuję bardzo za odpowiedź, tak wygląda mój plik .pro

QT       += core gui network opengl

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Gomoku-klient
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp \
    client.cpp \
    krzyzyk.cpp \
    kolko.cpp \
    plansza.cpp \
    pionek.cpp

HEADERS  += mainwindow.h \
    client.h \
    krzyzyk.h \
    kolko.h \
    plansza.h \
    pionek.h

FORMS    += mainwindow.ui

więc wszystkie pliki są chyba dodane. Odnośnie czyszczenia i budowania od początku już próbowałem, nie pomaga. A stworzenie osobnych klas do kółka i krzyżyka dziedziczących z klasy pionek wydawało mi się najłatwiejsze, bo chciałem wszystkie pionki przechowywać w jednej tablicy i potem w pętli wywoływać ich rysowanie.

3

W konstruktorach klas pochodnych brakuje wywołania konstruktora bazowego. Nie wiem czy to może powodować ten problem ale warto uzupełnić.

W klasie bazowej dodaj wirtualny destruktor.

Pokaż może kod gdzie tworzysz obiekty.

0

Dodanie do listy inicjalizacyjnej wywołania konstruktora, o którym mówiłeś pomogło, dzięki! A o co chodzi z tymi minusami? Dałem plusa, więc to jakby co to nie ja ;)

0

konstruktor domyślny to konstruktor domyślny i jest wywoływany domyślnie jeśli żaden konstruktor nie pojawia się na liście inicjalizacyjnej.
Zresztą twój błąd to jest wyraźna informacja z linker'a, a nie kompilatora i wyraźnie widać, że próbuje odnaleźć konstruktor domyślny.
To, że zaczęło działać akurat po tej poprawce to czysty przypadek (może po prostu cache się naprawił).
Odwróć poprawkę i sprawdź czy problem powróci, według mnie błąd nie powróci.
Jeśli jakimś cudem jednak problem powróci to wywal słowo explicit (jedyny powód dla którego, ten fix powyżej mógłby zadziałać) i spróbuj ponownie. To słowo kluczowe dla konstruktora domyślnego jest zbędne (potrzebne jest tylko dla konstruktorów, które mogą być wywołane z jednym argumentem, co może prowadzić do niechcianych konwersji automatycznych).
Jeśli zadziała po tym, znaczy, że natrafiłaś na jakiś dziwny błąd kompilatora/linkera. U mnie na gcc Linux działa bez problemu i nie odtwarzam twojego problemu.
Przyznaj się czym kompilujesz i na jakim systemie.

0

Kompilator - MVS 2010, Windows 7. Z tego co wiem, to Qt dużo lepiej działa pod Linuxem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1