0

I am writing a node addon that builds with node-gyp and I want to link with libraries from a large project (kaldi-asr) that is build using Makefiles.

It is infeasible for me to replicate the Makefile structure in the binding.gyp file, so I created an abstract class, and another class that extends it. This allows me to use the object having only the declaration of the abstract class that does not depend on any header or source of the kaldi project.


  class DecoderBase {
  public:
    // This method is a trick to make this header file
    // independent of the rest of kaldi.
    //
    // The implementation of this method will simply create
    // in instance of Decoder, that uses the kaldi types.
    //
    // The Decoder inherits DecoderBase, so it can 
    // be casted to DecoderBase, this class by the other
    // only uses the standard C++ types 
    static DecoderBase* CreateNew();  
    // give the ability to destroy an object from a pointer 
    // to this abstract class.
    // warning: deleting object of abstract class type 'TrecDecoderBase'
    // which has non-virtual destructor will cause undefined behaviour.
    virtual void Destroy() = 0; 
    virtual void InitDecoder() = 0;
    virtual void DeinitDecoder() = 0;
    virtual ~DecoderBase();
  };  

If the file is included more than once the compiler complains about class redefinition. If I remove the definitions from the virtual methods it fails with no typeinfo for class. Aparently it works if I leave as is and add #pragma once, is this enough, what if I include the header from different code units?

Is there a way to declare pure virtual functions without creating a class definition?

Adrian W
  • 4,563
  • 11
  • 38
  • 52
Bob
  • 13,867
  • 1
  • 5
  • 27
  • relevant: https://stackoverflow.com/questions/2979384/purpose-of-header-guards. Frankly, its a little odd that you encounter a problem due to missing include guards in this specifc case, because include guards are needed also for much simpler cases – 463035818_is_not_an_ai Jan 11 '22 at 17:36
  • I know about header guards, and I also know that certain definitions may lead to `thing redefined` at linking time if the header is included by multiple independent compilation units, this is why I would like to have the class declaration without a concrete definition. – Bob Jan 11 '22 at 17:48
  • 2
    It sounds like you're asking if you can do `virtual void DeinitDecoder() = 0;` outside of a class, just as a free function? The answer is no. There are some other options though, I think the closest would be to global (but not static) 'Init()' function pointer, and then re-assign that pointer to a specific function at runtime. As long as you never try to call it while it's still its default null value. – Ipiano Jan 11 '22 at 19:38
  • @lpiano So basically I can't tell the compiler that the implementation of a given function is mandatory unless I define the class. Any special reason why that's the case? – Bob Jan 11 '22 at 20:11
  • https://stackoverflow.com/questions/1787752/is-there-a-g-equivalent-to-visual-studios-declspecnovtable#1787870 – Sneftel Jan 11 '22 at 22:16
  • Unless your class contains only pure virtual functions, you will have to have a definition of that class. If you only have pure virtual, then you also have to provide a way to destroy created objects. One way to do it, is by using a Release function as it is done in COM. If you cannot be sure that all plug-ins are compiler with the same compiler version/run-time, then you need extra care to know what is binary compatible for your specific compiler (mostly C part of C++). – Phil1970 Jan 11 '22 at 22:39
  • @Phil1970 I think you have the answer my use case is very similar to that in COM, and I can be sure everything will be compiled with the same compiler. Other than pure virtual methods, my current class only has a static method that I use to create a subclass and return it casted to the base class. Since the client code will get a pointer it will have to explicitly delete the object in the end. If you can, please, post an example of it. – Bob Jan 12 '22 at 09:36

1 Answers1

0

This class does not generate code at all - and won't cause any collisions - so it would work, but it is definitely not good practice. How do you intend to link with your kaldi project? You will still have to link with it? What does prevent you from including the header files?

mmomtchev
  • 2,497
  • 1
  • 8
  • 23