c++ - 函数应该返回指向派生类还是基类的指针?

标签 c++ pointers polymorphism

当一个函数需要返回一个对象时。它应该通过指向 derived 还是 base 的指针返回它?

class B{

}

class D:public B{

}

// way 1: return pointer to derived
D* createDerived(){
    D* d = new D();
    return d;
}

// way 2: return pointer to base
B* createDerived(){
    B* d = new D();
    return d;
}

我听说过“面向接口(interface)而不是实现的程序”,它建议我们应该返回一个指向基的指针。然而我的直觉告诉我在这种情况下最好返回一个指向派生的指针,因为如果客户端代码使用基指针,这个函数仍然可以工作!另一方面,如果我们返回指向 base 的指针并且客户端代码使用派生指针,则这对它们不起作用。似乎通过返回一个更“具体”的指针,我们为客户端代码提供了更大的灵 active 。

另一种看待它的方式是从“program by contract”的角度来看。其中一项建议是尽可能少地 promise 。通过 promise 我们将返回一个非常具体的对象,我们遵循了这条规则。但是,如果我们返回一个基指针,在我看来,我们的希望更大。

哪个设计更好?我的上述推理是否正确?

关于如何制作模块化、可维护、可扩展的软件,我还有很多东西要学习,所以如果我的推理/结论不通俗易懂,请原谅。我对学习很感兴趣。非常感谢您抽出宝贵时间。

最佳答案

不可能笼统地回答这个问题。特别是,返回更多派生对象对该方法的 future 实现施加了额外的限制,而返回基类对调用者施加了更多限制。哪个最好取决于应用程序或库的设计,尤其是 BD 提供的功能范围以及 API 的总体设计。

一般来说,您希望返回最派生的类,或者笼统地说,最实用的类,这不会限制您 future 的实现选择。这允许您的客户有效地使用返回值,同时仍然允许您在未来更改实现。

使用派生类 D 的主要缺点是您向客户端公开了更多细节,这可能很难或不可能在以后逆转。

例如,假设您有一个方法 reverse(std::ReversibleContainer &cont),它获取一个容器并返回它的反转快照(即,对底层容器的更改不会影响返回的快照)。

在您的初始实现中,您可能决定将其实现为:

template<class BidirectionalIterator>
std::list<T> reverse(BidirectionalIterator &start, BidirectionalIterator &end) {
  std::vector output;
  std::copy(input.begin(), input.end(), back_inserter(output))
  return output;
}

稍后,您可能会意识到,在容器(和元素)不变的某些情况下,您可以避免底层数据的复制,例如:

ImmutableIterator reverse(ImmutableBiderectionalIterator &input) {
  return ReversingImmutableBiderectionalIterator(input);
}

此容器可以使用输入容器是只读的知识来返回输入容器的 View ,避免复制,复制只是简单地重新映射每次访问以产生与反转容器。

关于c++ - 函数应该返回指向派生类还是基类的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35516558/

相关文章:

PostgreSQL:查询结构与使用多态类型的函数结果类型不匹配 "anyelement"

c# - 是否可以创建使用 C# 或 C++ 代码的 Firefox 插件?如果是这样,如何?

c++ - 将Visual Studio 2017 Win32解决方案迁移到Linux解决方案

c++ - 由于模数运算符导致的编译代码问题

c++ - C 风格字符串、指针、数组

c - 当我将二维数组传递给函数 (tes).t 时,为什么声明 *(*(arr+1)+2) 不起作用

c++ - 什么时候使用指针成员变量?

c - 指向 C 中重新分配的内存块的多个指针

haskell - 我应该总是更喜欢更通用的类型而不是特定的类型吗?

c++ 模板和多态性没有合适的用户定义转换