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. Abstract member functions - strange phenomenon open to discussion:

Abstract member functions - strange phenomenon open to discussion:

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestiondiscussioncsharpvisual-studio
3 Posts 2 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.
  • N Offline
    N Offline
    Nick Nougat
    wrote on last edited by
    #1

    Hi! I recently stumbled over this interesting phenomenon using abstract member functions: The situation is this: We have an abstract base class that defines an interface. In the constructor of the base, a specific implementation dependent task needs to be carried out, so an abstract member function is invoked in the constructor. The behaviour of this member function is defined by derived classes. If no function body is provided for this abstract function in the base class, a linker error occurs (unresolved symbol). If we provide an empty body, in the base, everything links fine and the vtable lookup correctly resolves the implementation of the deriving class. The question is this: If the abstract function is resolved at run-time anyway, through use of vtables, why give me a compile-time error if I don't provide a body that will, due to it being an abstract function, never be used in the first place?! Is this a Microsoft specific behaviour bug/"feature", or is this standard ISO behaviour? I compiled this using MS VS .NET 2003 Thanks for any thoughts about this. Nick Here is some exaple code for you to check it out: #include class base { public: base() { abstractFunction(); } virtual ~base() {}; /* if you don't provide the function body with {}, a linker error occurs. Try uncommenting the part of the next line to make it work. */ virtual void abstractFunction() = 0 /*{}*/; }; class derived : public base { public: derived() {}; virtual ~derived() {}; // should be called by base::base() void abstractFunction() { printf("works\n"); } } testInstance; //create an instance right away... This code should print "works" to the console, since the As soon as you uncomment the function body of base::abstractFunction(), everything will link fine and work as expected.

    R 1 Reply Last reply
    0
    • N Nick Nougat

      Hi! I recently stumbled over this interesting phenomenon using abstract member functions: The situation is this: We have an abstract base class that defines an interface. In the constructor of the base, a specific implementation dependent task needs to be carried out, so an abstract member function is invoked in the constructor. The behaviour of this member function is defined by derived classes. If no function body is provided for this abstract function in the base class, a linker error occurs (unresolved symbol). If we provide an empty body, in the base, everything links fine and the vtable lookup correctly resolves the implementation of the deriving class. The question is this: If the abstract function is resolved at run-time anyway, through use of vtables, why give me a compile-time error if I don't provide a body that will, due to it being an abstract function, never be used in the first place?! Is this a Microsoft specific behaviour bug/"feature", or is this standard ISO behaviour? I compiled this using MS VS .NET 2003 Thanks for any thoughts about this. Nick Here is some exaple code for you to check it out: #include class base { public: base() { abstractFunction(); } virtual ~base() {}; /* if you don't provide the function body with {}, a linker error occurs. Try uncommenting the part of the next line to make it work. */ virtual void abstractFunction() = 0 /*{}*/; }; class derived : public base { public: derived() {}; virtual ~derived() {}; // should be called by base::base() void abstractFunction() { printf("works\n"); } } testInstance; //create an instance right away... This code should print "works" to the console, since the As soon as you uncomment the function body of base::abstractFunction(), everything will link fine and work as expected.

      R Offline
      R Offline
      Roger Allen
      wrote on last edited by
      #2

      You cannot call a virtual function of a derived class from a base class constructor. This is due to the order of construction. Base classes are built first so there is no vtable pointer available to call the correct function in the derived class, which is yet to be constructed. You need the function body as the virtual call compiles to the base class member function not the derived class one. You need a two stage construction method to handle what you need to do. x = new drieved; x.Initialise(); Where the initialise function calls the correct virtual functions once the object is fully constructed. If you vote me down, my score will only get lower

      N 1 Reply Last reply
      0
      • R Roger Allen

        You cannot call a virtual function of a derived class from a base class constructor. This is due to the order of construction. Base classes are built first so there is no vtable pointer available to call the correct function in the derived class, which is yet to be constructed. You need the function body as the virtual call compiles to the base class member function not the derived class one. You need a two stage construction method to handle what you need to do. x = new drieved; x.Initialise(); Where the initialise function calls the correct virtual functions once the object is fully constructed. If you vote me down, my score will only get lower

        N Offline
        N Offline
        Nick Nougat
        wrote on last edited by
        #3

        Ah, I see. That escaped my attention. Quite obvious though, come to think of it. (->silly me) So the fact that my example code works OK is only by chance and not a regular case and more complicated classes or a release version compile might produce unpredictable results. Thanks for the comment. Nick

        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