1

I'm wondering if the following is possible. I wanted my derived class dA to change func() to be pure virtual so that any classes derived from dA must implement func().

Code similar to below compiles without complaint under MSVC even though ddA does not implement func().

The compiler does complain about the below code (see comments). So my question now becomes: is this a standards-compliant way to achieve what I want?

class A {
   public:
      virtual void func() { /* Some base implementation. */ }
}

class dA : public A {
   public:
      void func() override = 0;   // Is this valid?
}

class ddA : public dA {
}

sleep
  • 4,855
  • 5
  • 34
  • 51
  • 1
    Does this answer your question? [Delete virtual function from a derived class](https://stackoverflow.com/questions/24609872/delete-virtual-function-from-a-derived-class) – Louis Go May 19 '21 at 03:17
  • 1
    _Code similar to below compiles without complaint under MSVC even though `ddA` does not implement `func()`._ Have you tried to make an instance of `ddA`. I tried to reproduce in g++. Your example compiled without complaints. This changed as soon as I added an `ddA obj;` because now it's a problem. (Abstract classes may not be instanced and `ddA` is such if `func()` is not overridden and defined.) [Test on coliru](http://coliru.stacked-crooked.com/a/749fb263e1b26557) – Scheff's Cat May 19 '21 at 05:22
  • Beside of this, I already have used derived classes which make an overridden function pure virtual even although a base class has it implemented. I did this explicitly to make intermediate classes non-instance-able. AFAIK, there is nothing wrong with this and I never noticed any unexpected behavior of the compiler concerning this. (I'm using VS2019, and have done so with VS2013, VS2008.) – Scheff's Cat May 19 '21 at 05:27
  • @Scheff you're right, it behaves as I expect if I add `ddA obj`. I forgot that in the case of my class, it only gets instantiated via scripting at runtime (via a meta object system), so the compiler wasn't aware of the instantiation. Updated the question. – sleep May 19 '21 at 09:39
  • IMHO, this doesn't change anything. Even a meta-system has to `new` the instance somewhere. Either this will complain about the incomplete class or (if it is achieved with a hacky trick) you just will run into a crash when something tries to call the `nullptr` for the pure virtual function from v-table. (I once managed this already somehow although I don't remember anymore how I did this achieve, and it was clearly my fault in this case...) – Scheff's Cat May 19 '21 at 10:01
  • When I first posted the question I hadn't run the code, I'd only compiled it. Indeed the meta-object system throws a runtime error that it cannot instantiate the class. But the compiler wasn't aware. I'm using Qt's QML runtime type registration APIs (qmlRegisterType() and friends). I suspect that if I instead used the QML_ELEMENT macro to register the types then I would get errors at compile-time. But I'm using cmake and unfortunately this macro only works with qmake. – sleep May 19 '21 at 12:56

1 Answers1

1

Pure virtual function should be declared in parent class. Consider the code below: '''

class Shape {
public:
    Shape(int init_x, int init_y) : x(init_x), y(init_y) {}

    virtual void scale(int s) = 0;
    virtual void print() = 0;
protected:
    int x;
    int y;
};

These functions should be implemented in children:

class Rect : public Shape {
public:
    Rect(int init_x, int init_y, int w, int h);
    virtual void scale(int s) { //implementation }
    virtual void print() { //implementation }
private:
    int width;
    int height;
};

However you don't have to implement virtual functions in subclasses since it had been implemented in super class:

Pure virtual function make your class abstract so you can't use its instances.

Saeed All Gharaee
  • 1,546
  • 1
  • 14
  • 27