In C++ an interface can be implemented by a class whose methods are pure virtual.
Such a class could be part of a library to describe what methods an object should implement to be able to work with other classes in the library:
class Lib::IFoo
{
    public:
        virtual void method() = 0;
};
:
class Lib::Bar
{
    public:
        void stuff( Lib::IFoo & );
};
Now I want to to use class Lib::Bar, so I have to implement the IFoo interface. 
For my purposes I need a whole of related classes so I would like to work with a base class that guarantees common behavior using the NVI idiom:
class FooBase : public IFoo // implement interface IFoo
{
    public:
        void method(); // calls methodImpl;
    private:
        virtual void methodImpl();
};
The non-virtual interface (NVI) idiom ought to deny derived classes the possibility of overriding the common behavior implemented in FooBase::method(), but since IFoo made it virtual it seems that all derived classes have the opportunity to override the FooBase::method(). 
If I want to use the NVI idiom, what are my options other than the pImpl idiom already suggested (thanks space-c0wb0y).
I think you've got your NVI pattern around the wrong way: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface
Not sure if that solves your issue though.
class IFoo
{
    public:
       void method() { methodImpl(); }
    private:
       virtual void methodImpl()=0;
};
class FooBase : public IFoo // implement interface IFoo
{
    private:
        virtual void methodImpl();
};
Here's an example of why you might do this using a reader that reads from XML and another from DB. Note that common structure is moved into the NVI readFromSource, while non-common behaviour is moved into the private virtual getRawDatum. This way logging and error checking is only needed in the one function.
class IReader
{
  public:
    // NVI
    Datum readFromSource()
    {
       Datum datum = getRawDatum();
       if( ! datum.isValid() ) throw ReaderError("Unable to get valid datum");
       logger::log("Datum Read");
       return datum;
    }
  private:
    // Virtual Bits
    Datum getRawDatum()=0;
};
class DBReader : public IReader
{
  private:
    Datum getRawDatum() { ... }
};
class XmlReader : public IReader
{
   private:
     Datum getRawDatum() { ... }
};
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With