Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6678123
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T04:12:19+00:00 2026-05-26T04:12:19+00:00

I have tried to answer this myself, by looking up several questions at StackOverflow.

  • 0

I have tried to answer this myself, by looking up several questions at StackOverflow. And although I think I understand this correctly, I can’t fix this. Which, leaves me with the only obvious observation: I still don’t get it.

I have made a summary of the questions at the bottom of this post, everything in between is information I have gathered and context for this question.

So, I get it that when you have a base class, and a derived class, your deconstructor should be marked virtual in the base class. To allow polymorphism.

But, I cannot seem to get my code to compile, or when it does compile, it does not link due ‘undefined references’. I have been changing back and forth, but I never seem to get out of this cycle.

Basically I have an interace, defined like this:

#ifndef GUIELEMENT_H_
#define GUIELEMENT_H_

class GuiElement {
    public:
    virtual ~GuiElement();
    virtual void draw() = 0;
};

#endif /* GUIELEMENT_H_ */

I have several objects extending from this. A simple relation is GuiWindow (directly derives from GuiElement):

#ifndef CGUIWINDOW_H_
#define CGUIWINDOW_H_

#include <assert.h>
#include <cstddef>

#include "../GuiElement.h"
#include "../GuiInteractionDelegate.h"

class GuiWindow : public GuiElement {

    public:
        GuiWindow(GuiInteractionDelegate * guiInteractionDelegate) {
            assert(guiInteractionDelegate);
            interactionDelegate = guiInteractionDelegate;
        }

        ~GuiWindow() {
            //delete interactionDelegate;
        }

        // called each frame, delegates its behavior to the given concrete cGuiWindowDelegate class.
        void interact() {
            interactionDelegate->interact(this);
        }

    private:
        GuiInteractionDelegate * interactionDelegate;

};

#endif /* CGUIWINDOW_H_ */

This code does not link, gives me:

undefined reference to `GuiElement::~GuiElement()’

I thought it was sufficient to have an implementation in the GuiWindow class? Is that correct?

The next thing, which is really bugging me, is that I also have an abstract class derived from GuiElement, and concrete implementations on top of that. Basically giving:
GuiElement->GuiShape->GuiButton

Here is the header of GuiShape:

#ifndef GUISHAPE_H_
#define GUISHAPE_H_

#include "../GuiElement.h"
#include "../../gameobjects/Rectangle.h"

class GuiShape : public GuiElement {

    public:
        GuiShape(Rectangle * rect);
        GuiShape(int x, int y, int width, int height);

        ~GuiShape();

        void draw();

        void setX(int value) { rectangle->setStartX(value);     }
        void setY(int value) { rectangle->setStartY(value);     }

        Rectangle * getRectangle() { return rectangle; }

        bool isMouseOverShape();

        void setColors(int darkBorder, int lightBorder, int inner);

        int getDarkBorderColor() { return darkBorderColor; }
        int getLightBorderColor() { return lightBorderColor; }
        int getInnerColor() { return innerColor; }

    protected:
        Rectangle * rectangle;

    private:
        bool rectangleOwner;
        int darkBorderColor;
        int lightBorderColor;
        int innerColor;
};

And finally GuiButton:

#ifndef CGUIBUTTON_H_
#define CGUIBUTTON_H_

#include <sstream>
#include <string>

#include "allegro.h"

#include "../../gameobjects/Rectangle.h"
#include "GuiShape.h"

class GuiButton : public GuiShape {

    public:
        GuiButton(Rectangle * rect, std::string theLabel);
        GuiButton(int x, int y, int width, int height, std::string theLabel);
        ~GuiButton();

        void draw();

        std::string * getLabel() {
            return label;
        }

        BITMAP * getBitmap() { return bitmap; }
        void setBitmap(BITMAP * value) { bitmap = value; }
        void setHasBorders(bool value) { hasBorders = value; }
        void setPressed(bool value) { pressed = value; }

        bool shouldDrawPressedWhenMouseHovers() { return drawPressedWhenMouseHovers; }
        bool shouldDrawBorders() { return hasBorders; }
        void setDrawPressedWhenMouseHovers(bool value) { drawPressedWhenMouseHovers = value; }
        bool isPressed() { return pressed; }

    private:
        std::string * label;
        bool drawPressedWhenMouseHovers;
        bool hasBorders;
        bool pressed;
        BITMAP * bitmap;

        void drawBackground();
        void drawLighterBorder();
        void drawDarkerBorder();
        void drawButtonUnpressed();
        void drawButtonPressed();
};

#endif /* CGUIBUTTON_H_ */

Which leads me to the following questions:

  • What is the best way to use virtual deconstructors where objects are derived from A->B->C ?
  • Should C only be the concrete virtual? And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
  • Why would I get ‘undefined references’ with the straight-forward implementation of A->B ? (GuiElement->GuiWindow)

Thanks in advance for your help!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T04:12:19+00:00Added an answer on May 26, 2026 at 4:12 am

    What is the best way to use virtual deconstructors where objects are derived from A->B->C ?

    mark the base’s (or all) destructor as virtual.

    Should C only be the concrete virtual? And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)

    Not sure what you mean by “concrete virtual” but a class with members that need destroying should destroy them in it’s own destructor. No exceptions. when ~C is called, it destroys it’s own stuff, and then ~B will be called automatically. The virtual just makes absolutely sure that ~C is called first.

    Why would I get ‘undefined references’ with the straight-forward implementation of A->B ? (GuiElement->GuiWindow)

    virtual ~GuiElement(); tells the compiler that the class has a destructor that will be defined later. You wanted either:

    // There is no definition, cannot make a local "GuiElement" variable
    // They can only make local "GuiButton" or other derived.
    // You can still have pointers to a GuiElement.
    // This is called "pure virtual"
    virtual ~GuiElement() = 0; 
    

    or:

    // There is a definition, someone can make a local "GuiElement" variable
    virtual ~GuiElement()  {};
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have tried my best to answer this question myself through research but I
Ok, I have tried searching around for this answer, but with no luck. I
I've tried Google, but I can't find the answer to this simple question. I
I have been looking all over the Internet for an answer to this question
I have tried to work this out myself (even bought a Kindle book!), but
So I have been asking questions here trying to get the answer for myself
First things first ive tried to fix this myself for hours and spent a
I have tried this... Dim myMatches As String() = System.Text.RegularExpressions.Regex.Split(postRow.Item(Post), \b\#\b) But it is
Hey, guys, I tried to ask this yesterday but I didn't explain myself clearly
I seem to have backed myself up into a corner with this. I'm sure

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.