0
  1. I have a base class and a derived class and a bunch of methods defined as virtual which are overridden in the derived class.
  2. I have an instance of the derived class assigned to a base pointer "myPointer" so the derived class virtual methods are called.
  3. Is it possible to "cast" the "myPointer" to a pointer pointing to the actual base instance and hence the base virtual methods are invoked through the new "casted pointer"?.
  4. I know about myPointer->Base::MyMethod(); so that is not what I want. I want to do something like:

    Base* myPointer = new Derived();
    Base* actualBasePointer = (some kind of case) myPointer;
    actualBasePointer->MyMethod(); // this invokes the base virtual method. 
    
10
  • Well, you could copy the object using object slicing, but that's not the same as casting Commented Jan 1, 2019 at 20:25
  • 6
    Regarding point 4, why don't you want to do something like that? What is the real and actual problem you want to solve? What is the reason for you wanting the "base instance"? Commented Jan 1, 2019 at 20:25
  • 1
    In what way do you hope your hypothetical actualBasePointer->MyMethod() call would behave differently than myPointer->Base::MyMethod() call? What is it you don't like about the latter, that you hope to "fix" with the former? Commented Jan 1, 2019 at 20:27
  • 1
    @Igor Tandetnik: actualBasePointer->MyMethod() behaves differently from what OP intends if Base::MyMethod() itself calls another virtual method of Base, which has been overridden in Derived . Commented Jan 1, 2019 at 20:30
  • 1
    @StephanLechner Well OK, if one wants to completely discard the Derived identify, then slicing it is: Base actualBase = *myPointer; actualBase.MyMethod(); Won't work for arbitrary Base (e.g. one that is an abstract class). Commented Jan 1, 2019 at 20:33

3 Answers 3

2

A Base* is a Base*. There is no "variant" that disables virtual dispatch / polymorphism, nor is there a type of cast to give you a different kind of pointer that does so.

Either your functions are virtual or they're not, and it would be really confusing if you could switch that on and off.

Instead, have alternative, non-virtual functions in your class that do what you need. I would recommend that you find a way to make these private to avoid confusion with the existing public virtual functions — generally this means they will be purely for utility/internal purposes. If this means you can't use them for the goal you have in mind, I'd advise reviewing your approach.

Alternatively, stick with the clear and well-known myPointer->Base::MyMethod() — simply knowing about it already doesn't seem like a good reason not to use it.

Sign up to request clarification or add additional context in comments.

Comments

0

Though a derived class object is composed out of its base class objects as far as non-static data members are concerned, the connection between virtual methods to their implementations in the derived class (or the base class, if a method is not overridden) is fixed and tightly coupled with the derived class object. So there is no way to generate a "view to the object's vtable" as if it where that of a Base class object. You can just refer directly to a specific implementation of a method by writing myPointer->Base::MyMethod(), yet this must be expressed explicitly with each call and it will not prohibit dynamic binding if Base::MyMethod() itself calls other virtual methods.

The only way to achieve that the derived class object behaves like a base class object is using object slicing, i.e. assigning a derived class object to an instance (not a pointer or reference) of the base class:

class Base {
public:
    int x = 10;

    virtual void printX() const {
        printInt(x);
    }
protected:
    virtual void printInt(int i) const {
        cout << "Base_printInt: " << i;
    }
};

class Derived : public virtual Base {
protected:
    virtual void printInt(int i) const override {
        cout << "Derived_printInt: " << i;
    }

};

int main() {
    Derived d;

    Base b = static_cast<Base>(d);

    b.printX();
}

Output:

Base_printInt: 10

1 Comment

Doesn't this make a copy?
0

No, you cannot disable virtual dispatch in any such manner.
However I would recommend this design pattern if you do need this behavior.

class StaticBase { 

    void foo() { /*default implementation*/ }

} 

class VirtualBase : StaticBase {

   StaticBase& as_base() { 
       return static_cast<StaticBase&>(*this); 
   }

   virtual void foo() { return StaticBase::foo(); }
}

class Derived : VirtualBase { 

   virtual void foo() { /* specialization */ }
}

That way you can do things like....

VirtualBase* vbase = new Derived(); 
vbase->foo();            //derived implementation 
vbase->as_base().foo();  //default implementation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.