C ++ unique_ptr <Base> to point to ptr from Derived

I have the following code:

class Base{
public:
    virtual void do_something(int a) = 0;
    virtual ~Base();

};

template<typename T>
class Concrete : public Base{

    T _t;
public:
    Concrete(){};
    virtual void do_something(int a);
    virtual ~Concrete();
};

template<typename T>
void Concrete<T>::do_something(int a){
    std::cout << a << std::endl;
}
template<typename T>
Concrete<T>::~Concrete(){}

int main(int argc, char **argv) {


    std::unique_ptr<Base> b(new Concrete<int>());
    b->do_something(5);
}

      

However, the related outputs failed. Output:

Undefined symbols for architecture x86_64:
  "Base::~Base()", referenced from:
      Concrete<int>::~Concrete() in testbed_evaluator.o
      Concrete<int>::~Concrete() in testbed_evaluator.o
  "typeinfo for Base", referenced from:
      typeinfo for Concrete<int> in testbed_evaluator.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

      

I cannot figure out what I am doing wrong

+3


source share


3 answers


You promised the compiler a destructor for Base

, so it made calls to it. But then you never wrote it, so when the linker sees these calls it doesn't know what to do.

You can fix it as easily as change

virtual ~Base();

      



to

virtual ~Base() {}

      

The latter has a body; this is the real definition.

+8


source


Define a base class destructor

virtual ~Base() {}

      



Refer to the following example http://ideone.com/0PNWN6

+3


source


I got your example to compile and run:

  • Including iostream:

    #include <iostream>
    
          

  • Removing the virtual destructor ~ Base (), which was never given an implementation. Another thing you could do is provide a no-op implementation, for example:

    virtual ~Base(){};
    
          

  • Using the standard pointer with the 'new' keyword:

    int main(int argc, char **argv) {      
        Base* b = new Concrete<int>();
        b->do_something(5);
     }
    
          

These things will make your example work. If you will, let me comment on the template. Your implementation expects doSomething () to always use int. However, templates are used when you want your implementation to be flexible enough to work with any type.

+1


source







All Articles