Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. a link error in C++ programming

a link error in C++ programming

Scheduled Pinned Locked Moved C / C++ / MFC
c++helpquestion
7 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    richardye
    wrote on last edited by
    #1

    I create an abstract class and a class derived from it. I know that an abstract class's object cannot be created until all its pure virtual functions are redefined within their derived class. However, How about the constructor and destructor functions? As they are special class functions, they can not be redefined within their derived class. class Abstract_base { public: virtual ~Abstract_base()=0; virtual void interface1() const = 0; virtual const char* mumber() const { return _mumble; }; protected: char *_mumble; }; class Concrete_derived : public Abstract_base { public: Concrete_derived() { }; virtual void interface1() const {}; }; int main { Concrete_derived trouble; return 0; } The code above has link eror.(error LNK2019) If I change "virtual ~Abstract_base()=0;" to "virtual ~Abstract_base()=0; {}", the link error disappeared. Why shall we add "virtual" to the destructor function? Can you give me some explanation? many thanks Tomorrow is another day!

    C D I 3 Replies Last reply
    0
    • R richardye

      I create an abstract class and a class derived from it. I know that an abstract class's object cannot be created until all its pure virtual functions are redefined within their derived class. However, How about the constructor and destructor functions? As they are special class functions, they can not be redefined within their derived class. class Abstract_base { public: virtual ~Abstract_base()=0; virtual void interface1() const = 0; virtual const char* mumber() const { return _mumble; }; protected: char *_mumble; }; class Concrete_derived : public Abstract_base { public: Concrete_derived() { }; virtual void interface1() const {}; }; int main { Concrete_derived trouble; return 0; } The code above has link eror.(error LNK2019) If I change "virtual ~Abstract_base()=0;" to "virtual ~Abstract_base()=0; {}", the link error disappeared. Why shall we add "virtual" to the destructor function? Can you give me some explanation? many thanks Tomorrow is another day!

      C Offline
      C Offline
      Cedric Moonen
      wrote on last edited by
      #2

      You shouldn't put a =0 after your destructor. This means that the function is a pure virtual function: the function be implemented by all child classes. It is quite odd to put that on a destructor. A destructor is always required (one is supplied by default if you don't write it yourself) so, you need to provide a body. Which you did by adding {}. This is just an empty body, but it is still a body. If you don't provide a body for your destructor, you'll get a linker error.


      Cédric Moonen Software developer
      Charting control [v1.2]

      L 1 Reply Last reply
      0
      • C Cedric Moonen

        You shouldn't put a =0 after your destructor. This means that the function is a pure virtual function: the function be implemented by all child classes. It is quite odd to put that on a destructor. A destructor is always required (one is supplied by default if you don't write it yourself) so, you need to provide a body. Which you did by adding {}. This is just an empty body, but it is still a body. If you don't provide a body for your destructor, you'll get a linker error.


        Cédric Moonen Software developer
        Charting control [v1.2]

        L Offline
        L Offline
        led mike
        wrote on last edited by
        #3

        Cedric Moonen wrote:

        It is quite odd to put that on a destructor.

        What? It is exactly what any abstract base class should have. Did you ever read Effective C++ by Scott Meyers?

        C 1 Reply Last reply
        0
        • R richardye

          I create an abstract class and a class derived from it. I know that an abstract class's object cannot be created until all its pure virtual functions are redefined within their derived class. However, How about the constructor and destructor functions? As they are special class functions, they can not be redefined within their derived class. class Abstract_base { public: virtual ~Abstract_base()=0; virtual void interface1() const = 0; virtual const char* mumber() const { return _mumble; }; protected: char *_mumble; }; class Concrete_derived : public Abstract_base { public: Concrete_derived() { }; virtual void interface1() const {}; }; int main { Concrete_derived trouble; return 0; } The code above has link eror.(error LNK2019) If I change "virtual ~Abstract_base()=0;" to "virtual ~Abstract_base()=0; {}", the link error disappeared. Why shall we add "virtual" to the destructor function? Can you give me some explanation? many thanks Tomorrow is another day!

          D Offline
          D Offline
          David Crow
          wrote on last edited by
          #4

          richardye wrote:

          Can you give me some explanation?

          You must provide a definition of the pure virtual destructor.


          "Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman

          "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

          1 Reply Last reply
          0
          • R richardye

            I create an abstract class and a class derived from it. I know that an abstract class's object cannot be created until all its pure virtual functions are redefined within their derived class. However, How about the constructor and destructor functions? As they are special class functions, they can not be redefined within their derived class. class Abstract_base { public: virtual ~Abstract_base()=0; virtual void interface1() const = 0; virtual const char* mumber() const { return _mumble; }; protected: char *_mumble; }; class Concrete_derived : public Abstract_base { public: Concrete_derived() { }; virtual void interface1() const {}; }; int main { Concrete_derived trouble; return 0; } The code above has link eror.(error LNK2019) If I change "virtual ~Abstract_base()=0;" to "virtual ~Abstract_base()=0; {}", the link error disappeared. Why shall we add "virtual" to the destructor function? Can you give me some explanation? many thanks Tomorrow is another day!

            I Offline
            I Offline
            Iain Clarke Warrior Programmer
            wrote on last edited by
            #5

            Destructors *are* different from normal memeber functions. If you have a normal member function, you can choose whether to call the ancestor's implementation or not. eg:

            void CMyDialog::DoDataExchange (CDataExchange *pDX)
            {
            ....
            CDialog::DoDataExchange (pDX);
            }

            While it's good practise to call the ancester method in the example above, it's not required to by C++ - so DoDataExchange could have been a virtual =0 member. BUT... Destructor's don't get the choice of whether to call the ancester destructor or not. When CMyDialog::~CMyDialog is finished, CDialog::~CDialog is run whether you want it or not. In which case, it needs to exist - even if it's very boring (eg { } ) as you've found out. I hope that helps a little. Iain.

            R 1 Reply Last reply
            0
            • L led mike

              Cedric Moonen wrote:

              It is quite odd to put that on a destructor.

              What? It is exactly what any abstract base class should have. Did you ever read Effective C++ by Scott Meyers?

              C Offline
              C Offline
              Cedric Moonen
              wrote on last edited by
              #6

              led mike wrote:

              Did you ever read Effective C++ by Scott Meyers?

              Nope but I was planning to buy it soon :-D

              led mike wrote:

              It is exactly what any abstract base class should have.

              Yes, I see. I never done it that way: I always used at least one pure virtual function.


              Cédric Moonen Software developer
              Charting control [v1.2]

              1 Reply Last reply
              0
              • I Iain Clarke Warrior Programmer

                Destructors *are* different from normal memeber functions. If you have a normal member function, you can choose whether to call the ancestor's implementation or not. eg:

                void CMyDialog::DoDataExchange (CDataExchange *pDX)
                {
                ....
                CDialog::DoDataExchange (pDX);
                }

                While it's good practise to call the ancester method in the example above, it's not required to by C++ - so DoDataExchange could have been a virtual =0 member. BUT... Destructor's don't get the choice of whether to call the ancester destructor or not. When CMyDialog::~CMyDialog is finished, CDialog::~CDialog is run whether you want it or not. In which case, it needs to exist - even if it's very boring (eg { } ) as you've found out. I hope that helps a little. Iain.

                R Offline
                R Offline
                richardye
                wrote on last edited by
                #7

                You mean that no matter how I should define the pure destructor function. But there is still something I cannot understand very well. If in your class you have a pure member function, you must show that any class derived from it should implement your pure function. Isn't it? But if you define a destructor function to be pure, you cannot implement it in your derived class and you have to add "{}" in your base class. I think it is meaningless. Why shall we use pure destructor function in a class? Many thanks. Tomorrow is another day!

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups