简体   繁体   中英

Why can I not instantiate a const instance of a class when non-const virtual methods are missing?

Why is this not legal?

class Base {
public:
    virtual void bar() = 0;
    virtual void barc() const = 0;
};

class Derived: public Base {
public:
    // deliberately omitted
    // virtual void bar()
    virtual void barc() const override { };
};

int main() {
    const Derived b;
    b.barc();
    // b.bar();
    // fails as expected with "passing 'const Bar' as 'this' argument discards qualifiers"
}

This fails with the following error, because I did not define virtual void bar() :

prog.cpp: In function 'int main()':
prog.cpp:16:12: error: cannot declare variable 'd' to be of abstract type 'Derived'
  const Derived d;
            ^
prog.cpp:10:7: note:   because the following virtual functions are pure within 'Derived':
 class Derived : public Base{
       ^
prog.cpp:6:15: note:    virtual void Base::bar()
  virtual void bar() = 0;

But I can't invoke bar here anyway, because that method is not marked const. If bar were defined, would there any legal way to invoke d.bar() indirectly anyway?

  • Is using a const_cast allowed?

  • Can I get in trouble with casting a super/subclass?

If not, then why must I define it?

I think there are a few blunt ways to put this:

  1. Because there is only one vtable. The const and non-const objects share it.

  2. Because you might const_cast the const object to a non-const one.

  3. Because while the object is being constructed, it's not const.

  4. Because constness is not a property of the object itself, it's a property attached to an object or reference that limits access to parts of the object.

The further questions were:

Is using a const_cast allowed?

Yes. But what you do with the const_casted reference can quickly lead to "undefined behaviour". This does not mean "the world may end", as some would have you believe. What it means is, "the c++ standard does not define this behaviour - if the compiler, the hardware or the OS wish to, that's up to them". ie whatever you do with that const_casted reference is unlikely to be portable.

Can I get in trouble with casting a super/subclass?

Casts are an open invitation for trouble.

You cannot instantiate an abstract class. End of story.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM