为什么C++中没有基类?

sle*_*ica 84 c++ language-design

快速问题:从设计的角度来看,为什么在C++中,没有母语所有的基类,通常object在其他语言中是什么?

Cap*_*ffe 115

确切的裁决可以在Stroustrup的常见问题解答中找到.简而言之,它没有传达任何语义含义.这将是一个成本.模板对容器更有用.

为什么C++没有通用类对象?

  • 我们不需要一个:在大多数情况下,泛型编程提供静态类型安全的替代方案.使用多重继承处理其他情况.

  • 没有有用的通用类:真正的通用不带有自己的语义.

  • "通用"类鼓励对类型和接口进行粗略的思考,并导致过多的运行时检查.

  • 使用通用基类意味着成本:对象必须被堆分配为多态的; 这意味着内存和访问成本.堆对象自然不支持复制语义.堆对象不支持简单的作用域行为(这使资源管理变得复杂).通用基类鼓励使用dynamic_cast和其他运行时检查.

  • 我们不需要没有/基类对象/我们不需要/思考控制...;) (83认同)
  • `对象必须被堆分配为多态的 - 我不认为这种说法通常是正确的.您绝对可以在堆栈上创建多态类的实例,并将其作为指向其基类之一的指针传递,从而产生多态行为. (10认同)
  • 在Java中,当`Bar`没有继承`Foo`时,试图将引用转换为```````'*****************************在C++中,尝试将指向Foo的指针转换为指向Bar的指针可以及时发送机器人来杀死Sarah Connor. (5认同)
  • @Piskvor - 大声笑我想看音乐视频! (3认同)
  • @supercat这就是我们使用dynamic_cast <>的原因.为了避免SkyNet和神秘地出现切斯特菲尔德沙发. (3认同)

Jon*_*ing 44

让我们首先想一想为什么你想要首先拥有一个基类.我可以想到几个不同的原因:

  1. 支持将处理任何类型对象的通用操作或集合.
  2. 包括所有对象共有的各种过程(例如内存管理).
  3. 一切都是对象(没有原语!).有些语言(比如Objective-C)没有这个,这让事情变得非常混乱.

这些是Smalltalk,Ruby和Objective-C品牌的语言具有基类的两个很好的理由(从技术上讲,Objective-C实际上没有基类,但是对于所有意图和目的,它确实如此).

对于#1,通过在C++中包含模板,可以避免需要在单个接口下统一所有对象的基类.例如:

void somethingGeneric(Base);

Derived object;
somethingGeneric(object);
Run Code Online (Sandbox Code Playgroud)

当你可以通过参数多态来保持类型完整性时,这是不必要的!

template <class T>
void somethingGeneric(T);

Derived object;
somethingGeneric(object);
Run Code Online (Sandbox Code Playgroud)

对于#2,而在Objective-C中,内存管理过程是类的实现的一部分,并且是从基类继承的,C++中的内存管理是使用组合而不是继承来执行的.例如,您可以定义一个智能指针包装器,它将对任何类型的对象执行引用计数:

template <class T>
struct refcounted
{
  refcounted(T* object) : _object(object), _count(0) {}

  T* operator->() { return _object; }
  operator T*() { return _object; }

  void retain() { ++_count; }

  void release()
  {
    if (--_count == 0) { delete _object; }
  }

  private:
    T* _object;
    int _count;
};
Run Code Online (Sandbox Code Playgroud)

然后,不是在对象本身上调用方法,而是在其包装器中调用方法.这不仅允许更通用的编程:它还允许您分离关注点(理想情况下,您的对象应该更关心它应该做什么,而不是在不同情况下应该如何管理它的内存).

最后,在一种既有原语又有像C++这样的实际对象的语言中,拥有基类(每个值的一致接口)的好处都会丢失,因为那时你有一些不符合该接口的值.为了在这种情况下使用基元,你需要将它们提升到对象中(如果你的编译器不会自动执行它).这会造成很多复杂化.

所以,对你的问题的简短回答:C++没有基类,因为通过模板进行参数多态,它不需要.

  • 对于第3点,我使用C#进行计数.C#具有_can_被装箱为`object`(`System.Object`)的原语,但它们不需要.对于编译器,`int`和`System.Int32`是别名,可以互换使用; 运行时在需要时处理装箱. (2认同)
  • 请注意,虽然这个(旧)答案演示了引用计数智能指针,但C++ 11现在有[`std :: shared_ptr`](http://www.cplusplus.com/reference/memory/shared_ptr/)改为使用. (2认同)

seh*_*ehe 15

C++变量的主要范例是按值传递,而不是传递给参数.强制从根导出所有内容Object会使它们按值传递它们.

(因为通过值接受Object作为参数,根据定义将其切片并移除其灵魂).

这是不受欢迎的.C++让您考虑是否需要值或引用语义,为您提供选择.这在性能计算中是一件大事.


Ell*_*ioh 6

问题是C++中有这样的类型!是的void.:-)可以安全地隐式转换任何指针void *,包括指向基本类型的指针,没有虚拟表的类和具有虚拟表的类.

由于它应该与所有这些类别的对象兼容,因此它void本身不能包含虚方法.如果没有虚函数和RTTI,就无法获得有关类型的有用信息void(它匹配每种类型,因此只能告诉每种类型的事物都是真的),但虚函数和RTTI会使简单类型非常无效并阻止C++被存在适用于具有直接存储器访问等的低级编程的语言

所以,有这样的类型.由于语言的低级特性,它只提供非常简约(实际上是空的)接口.:-)