unique_prts 是否允许隐式转换它们的包含类型?

Are unique_prts allowed to implicitly convert their containing type?

有人可以解释为什么我的 factory 函数是正确的吗? unique_ptr 是否默认进行动态转换?为什么 return 类型不必与 factory 函数类型相同?

#include <exception>
#include <iostream>
#include <memory>

struct Animal
{
  virtual void makeSound() { std::cout << "(...)" << std::endl; }
};

struct Cat : public Animal
{
  virtual void makeSound() { std::cout << "Meaw!" << std::endl; }
};

struct Dog: public Animal
{
  virtual void makeSound() { std::cout << "Woof!" << std::endl; }
};

struct ConfusedCat : public Cat
{
  virtual void makeSound() { std::cout << "Moooooh!" << std::endl; }
};

// Why is this factory function allowed like this?
std::unique_ptr<Animal> factory(const int i)
{
  if (i == 1)
    return std::unique_ptr<Cat>(new Cat());
  else if (i == 2)
    return std::unique_ptr<ConfusedCat>(new ConfusedCat());
  else if (i == 3)
    return std::unique_ptr<Dog>(new Dog());
  else
    return std::unique_ptr<Animal>(new Animal());
}

int main()
{
  try
  {
    auto animal0 = factory(0);
    auto animal1 = factory(1);
    auto animal2 = factory(2);
    auto animal3 = factory(3);

    animal0->makeSound();
    animal1->makeSound();
    animal2->makeSound();
    animal3->makeSound();
  }
  catch ( std::exception &e )
  {
    std::cout << e.what() << std::endl;
    return 1;
  }

  return 0;
}

在派生到 public 的 C++ 中,基指针转换是隐式的,不需要强制转换。

同样适用于所有标准和升压智能指针。

参见 std::unique_ptr::unique_ptr 上的重载 6:

std::unique_ptr<Derived> is implicitly convertible to std::unique_ptr<Base> through the overload (6)