1

I have two classes, Base which contains virtual method and D which contains overload that method. I want to create a variable with Base type, than pass there class D which inherits class Base. It's my implementation:

#include <iostream>
#include <vector>
#include <memory>
#include <cstdio>
#include <fstream>
#include <cassert>
#include <functional>


class Base {
public:
  virtual void bar() { std::cout << "B::bar\n"; }
  //virtual ~Base() = default;
};

typedef Base* Maker();
Maker* arr[10];

class D : Base
{
public:
    D() { std::cout << "D::D\n";  }
    ~D() { std::cout << "D::~D\n";  }
    void bar() override { std::cout << "D::bar\n";  }
};

template <class T>
Base* make(){
    return new T;
}

int main()
{
  std::unique_ptr<Base> p1(new D);
  p1->bar();

  //arr[0] = make<D>();

  return 0;
}

Btw, it's working with structs, but when I try to implement that though classes I'll get error.

lostsky25
  • 85
  • 1
  • 10

2 Answers2

4

D inherits from B privately. Therefore, D* is not convertible to B*. You likely want class D : public Base { ... };

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
  • Yes, I changed it, it's working. However, when I try to do something like this: `D *d1 = new D();` `std::vector> object;` `object.push_back(d1);` I'll get error... Can I use `std::unique_ptr` in `std::vector`? – lostsky25 Jun 06 '20 at 21:02
  • Make it `object.emplace_back(d1);` – Igor Tandetnik Jun 06 '20 at 21:06
  • @lostsky25 yes, you can use `unique_ptr` in a `vector`. Storing smart pointers in containers is one of the main reasons why `unique_ptr` and `shared_ptr` and move semantics were invented, since `auto_ptr` can't be used in containers – Remy Lebeau Jun 06 '20 at 21:15
  • @IgorTandetnik note that `object.emplace_back(d1);` will leak `d1` if `emplace_back()` throws. It would be safer to wrap `d1` in a `unique_ptr` first and then move that into the vector. [What is the correct usage of std::unique_ptr while pushing into std::vector](https://stackoverflow.com/questions/14484183/) – Remy Lebeau Jun 06 '20 at 21:18
0

The compilation error has two reasons, and both must be fixed.

class D : Base

Base is privately inherited, so only members of D can convert a pointer to D to a pointer to B, you must inherit publicly:

class D : public Base

Second problem is here:

typedef Base* Maker();

Maker* arr[10];

// ...

arr[0] = make<D>();

arr is an array of function pointers. "Make()" is an expression that evaluates to a function call that returns a Base *. Assigning a Base * to some function pointer doesn't make any sense, whatsoever. You meant:

arr[0] = &make<D>;

With both fixes, the shown code compiles.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148