www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why do abstract class functions require definitions?

reply FiveNights <fnpi fnaf.com> writes:
Every so often I'll get a compiler error that isn't particularly 
clear on what's wrong and eventually I'll figure out that what's 
causing it is having a function in an abstract class somewhere 
that isn't defined:

abstract class SomeClass {
     int someVariable;
     void someFunction();
}
the solution is usually:
void someFunction(){}

Usually the abstract class is a converted interface, but it 
turned out that I needed to include a variable for it to work out 
and I just wasn't keen on remembering to put a mixin in each 
derived class.

I'm just wondering why I can't have an undefined function in an 
abstract class? I'd the compiler to say, "Hey, you forgot to put 
'someFunction()' in 'SomeDerrivedClass', go do something about 
that." when I end a function with a semi-colon in the base class 
and don't have it in the derrived. Everything just seems to break 
in cryptic ways unless I curly brace the function ending.
Sep 16 2015
next sibling parent Kagamin <spam here.lot> writes:
declare as
abstract void someFunction();
Sep 16 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-09-16 10:49, FiveNights wrote:
 Every so often I'll get a compiler error that isn't particularly clear
 on what's wrong and eventually I'll figure out that what's causing it is
 having a function in an abstract class somewhere that isn't defined:

 abstract class SomeClass {
      int someVariable;
      void someFunction();
 }
 the solution is usually:
 void someFunction(){}

 Usually the abstract class is a converted interface, but it turned out
 that I needed to include a variable for it to work out and I just wasn't
 keen on remembering to put a mixin in each derived class.

 I'm just wondering why I can't have an undefined function in an abstract
 class? I'd the compiler to say, "Hey, you forgot to put 'someFunction()'
 in 'SomeDerrivedClass', go do something about that." when I end a
 function with a semi-colon in the base class and don't have it in the
 derrived. Everything just seems to break in cryptic ways unless I curly
 brace the function ending.
I'm guessing you see a link error. The reason you see that instead of a compile error is because D supports separate compilation. Meaning that the method could be implemented in a different library that are resolved during link time. As already answered in another post, the solution is to prefix the method declaration with "abstract". -- /Jacob Carlborg
Sep 16 2015
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Wednesday, 16 September 2015 at 09:31:25 UTC, Jacob Carlborg 
wrote:
 On 2015-09-16 10:49, FiveNights wrote:
 Every so often I'll get a compiler error that isn't 
 particularly clear
 on what's wrong and eventually I'll figure out that what's 
 causing it is
 having a function in an abstract class somewhere that isn't 
 defined:

 abstract class SomeClass {
      int someVariable;
      void someFunction();
 }
 the solution is usually:
 void someFunction(){}

 Usually the abstract class is a converted interface, but it 
 turned out
 that I needed to include a variable for it to work out and I 
 just wasn't
 keen on remembering to put a mixin in each derived class.

 I'm just wondering why I can't have an undefined function in 
 an abstract
 class? I'd the compiler to say, "Hey, you forgot to put 
 'someFunction()'
 in 'SomeDerrivedClass', go do something about that." when I 
 end a
 function with a semi-colon in the base class and don't have it 
 in the
 derrived. Everything just seems to break in cryptic ways 
 unless I curly
 brace the function ending.
I'm guessing you see a link error. The reason you see that instead of a compile error is because D supports separate compilation. Meaning that the method could be implemented in a different library that are resolved during link time. As already answered in another post, the solution is to prefix the method declaration with "abstract".
Wouldn't the following behaviour be more useful as a default? abstract class Foo { void bar1() { } // non-abstract, obviously void bar2(); // abstract, because it's in an abstract class // (different from now) extern void bar3(); // non-abstract, but defined externally }
Sep 16 2015
next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/16/15 6:36 AM, Marc Schütz wrote:

 Wouldn't the following behaviour be more useful as a default?

      abstract class Foo {
          void bar1() { }     // non-abstract, obviously
          void bar2();        // abstract, because it's in an abstract class
                              // (different from now)
          extern void bar3(); // non-abstract, but defined externally
      }
My guess is that .di files need the bar2 syntax style. -Steve
Sep 17 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-09-16 12:36, Marc Schütz wrote:

 Wouldn't the following behaviour be more useful as a default?

      abstract class Foo {
          void bar1() { }     // non-abstract, obviously
          void bar2();        // abstract, because it's in an abstract class
                              // (different from now)
          extern void bar3(); // non-abstract, but defined externally
      }
Currently "extern" has the meaning, at least on Windows, that the symbol will be visible outside a dynamic library. -- /Jacob Carlborg
Sep 18 2015
parent reply Jakob Ovrum <jakobovrum gmail.com> writes:
On Friday, 18 September 2015 at 13:18:23 UTC, Jacob Carlborg 
wrote:
 On 2015-09-16 12:36, Marc Schütz wrote:

 Wouldn't the following behaviour be more useful as a default?

      abstract class Foo {
          void bar1() { }     // non-abstract, obviously
          void bar2();        // abstract, because it's in an 
 abstract class
                              // (different from now)
          extern void bar3(); // non-abstract, but defined 
 externally
      }
Currently "extern" has the meaning, at least on Windows, that the symbol will be visible outside a dynamic library.
That's `export`.
Sep 18 2015
parent Jacob Carlborg <doob me.com> writes:
On 2015-09-18 17:45, Jakob Ovrum wrote:

 That's `export`.
Right, my bad. D has too many attributes :) -- /Jacob Carlborg
Sep 19 2015