m.t*_*cey 4 c++ overloading hierarchy unique-ptr
我的印象是unique_ptr可以以与普通指针相同的方式推断类层次结构,但是当我尝试重载这样的函数时:
void func(unique_ptr<Derived1>& d1);
void func(unique_ptr<Derived2>& d2);
Run Code Online (Sandbox Code Playgroud)
然后调用这样的函数之一:
unique_ptr<Base> b = make_unique<Derived1>();
func(b);
Run Code Online (Sandbox Code Playgroud)
我收到一个错误说no instance of overloaded function "func" matches the argument list。b 的运行时类型是Derived1,所以我预计会调用第一个重载。
此外,当我unique_ptr从函数返回 a 时,编译器能够将派生类(?不确定合适的术语)转换为基类,以便像这样工作:
unique_ptr<Base> create(){
return make_unique<Derived1>();
}
Run Code Online (Sandbox Code Playgroud)
通常在我的代码中,我将变量声明为这样的函数的结果。它们被声明为基类,但具有派生的运行时类型,我想将它们传递给一个重载函数。
我如何以与使用涉及类层次结构的常规指针相同的方式重载函数?
您是对的,所有标准智能指针的隐式转换操作都为原始指针建模。这允许编译第二个片段,即
unique_ptr<Base> create(){
return make_unique<Derived1>();
}
Run Code Online (Sandbox Code Playgroud)
然而,关于第一个片段有一个误解,因为从来没有一个从基类到派生类的内置隐式向下转换。使用普通指针,
void func(Derived1* d1);
void func(Derived2* d2);
Base* b = new Derived1();
func(b);
Run Code Online (Sandbox Code Playgroud)
也不会编译。这在基本的 OOP 意义上是有意义的 - 通过基类接口查看继承层次结构中的对象,并隐藏实际的具体运行时类型。
如果您需要具有这种调度的设计,您需要阅读“访问者”设计模式,它实现了一种称为双重(或多重)调度的技术。但是实现这一点所需的样板数量给了你一个提示,为什么该语言不提供这种作为内置的调度。