polymorphic C++ references

前端 未结 7 1054
闹比i
闹比i 2020-12-09 09:07

I was wondering how you can do polymorphism with references, as opposed to pointers.

To clarify, see the following minimal example:

cl         


        
相关标签:
7条回答
  • 2020-12-09 09:41

    There's nothing odd. Polymorphisms works both for pointers and references:

    struct Base { };
    struct Derived : Base;
    
    void foo(Base &);
    
    int main() {
      Derived x;
      foo(x);    // fine
    }
    

    You're conflating this with another issue, namely creating a reference to a dynamic object:

    T * pt = new T;
    T & rt = *pt;
    
    T & x = *new T;  // same effect
    

    Note that it's generally very bad style to track a dynamic object only by reference, because the only way to delete it is via delete &x;, and it's very hard to see that x needs cleaning up.

    There are two immediate alternatives for your design: 1) make a a member object in B, or 2) make a a shared_ptr<A> or unique_ptr<A> and change the initalizer to a(new A1). It all depends on whether you actually need the polymorphic behaviour, i.e. if you have other constructors for B which assign a different derived class to a other than A1.

    0 讨论(0)
  • 2020-12-09 09:44

    This is indeed a bit odd. If you want a member-variable of type A1 (rather than a reference), why not just rearrange your code so that the definition of A1 appears before the definition of B?

    0 讨论(0)
  • 2020-12-09 09:45

    Still, is there a real need for dynamic memory allocation in this case?

    No. Just define A1 first and then make it a normal member of B.

    Polymorphism works just fine with both references and pointers.

    0 讨论(0)
  • 2020-12-09 09:57

    I realize this is a really old post but there is another option you have for handling references for dynamically allocated objects. You can assign a reference to the dynamically allocated object. Below is some dummy code to give you an idea of how this works.

    struct A
    {
      int b;
      virtual void print();
      A(int val):b(val) {}
    };
    
    struct A_child:public A
    {
      A_child(int val):A(val) {}
      void print();
    };
    
    void A:print()
    {
    cout<<"parent\n";
    }
    
    void A_child:print()
    {
    cout<<"child\n";
    }
    
    struct test_ref
    {
    A *& ref;
    test_ref(A * ptr) : ref(ptr)
    }
    
    int main()
    {
    
      test_ref parent(new A(12));
      parent.ref->print();
    
      test_ref child(new A_child(15));
      child.ref->print();
    } 
    

    To be honest I am not certain when this is a good idea. I just wanted to show an alternative approach where you dont have to dereference the dynamically allocated memory when initializing an object.

    I am also pretty certain dynamically allocating a pointer while initializing a class where the pointer is stored as a reference pointer will probably lead to a memory leak unless you can delete the reference pointer.

    0 讨论(0)
  • 2020-12-09 10:03

    Erm, is this not sufficient?

    #include <iostream>
    
    struct A;
    
    struct B
    {
      B(A& a);
    
      void foo();
    
      A& _a;
    };
    
    struct A
    {
      virtual void foo() =0;
    };
    
    struct A1 : public A
    {
      virtual void foo() { std::cout << "A1::foo" << std::endl; }
    };
    
    B::B(A& a) : _a(a) {}
    void B::foo() { _a.foo(); }
    
    
    int main(void)
    { 
      A1 a;  // instance of A1
      B b(a); // construct B with it
    
      b.foo();
    }
    
    0 讨论(0)
  • 2020-12-09 10:05

    Still, is there a real need for dynamic memory allocation in this case?

    Either the dynamic memory allocation or injecting the reference into B's ctor.

    0 讨论(0)
提交回复
热议问题