Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ typedef相对于派生类的优势?_C++_Templates_Forward Declaration - Fatal编程技术网

C++ typedef相对于派生类的优势?

C++ typedef相对于派生类的优势?,c++,templates,forward-declaration,C++,Templates,Forward Declaration,简言之,你说的和做的有什么区别 class MyClassList : list<MyClass> { }; 没有编译器错误,而不是 class MyClass; typedef list<MyClass> MyClassList; class-MyClass; typedef列表MyClassList; 我想不出有什么区别,但这让我想知道,在某些情况下,typedef可以被使用,而简单的派生类却不能 或者换一种说法,我有没有理由不把我所有的typedef列表都改成

简言之,你说的和做的有什么区别

class MyClassList : list<MyClass> { };
没有编译器错误,而不是

class MyClass;
typedef list<MyClass> MyClassList;
class-MyClass;
typedef列表MyClassList;
我想不出有什么区别,但这让我想知道,在某些情况下,typedef可以被使用,而简单的派生类却不能

或者换一种说法,我有没有理由不把我所有的typedef列表都改成SomeClassList;对于简单派生类,以便我可以很容易地提前声明它们,

在C++中,它是从STL容器派生的,所以不要这样做。
typedef
只是为现有类型创建了一个别名,所以
typedef std::list MyClassList
创建一个名为
MyClassList
的“新类型”,您现在可以按如下方式使用它:

MyClassList-lst


typedef
s更改为派生类是个坏主意。不要这样做。

typedef正是为了这个目的——别名类型名称。它非常地道,不会混淆任何熟悉C++的人。 但要解决为什么继承可能是个坏主意


std::list
没有虚拟析构函数。这意味着通过基类删除时,
MyClassList
不会调用其析构函数。所以这通常是不赞成的。在您的情况下,您无意将任何成员放入MyClassList中,因此这将成为一个毫无意义的点,直到下一个程序员将继承视为添加新成员/覆盖函数等的邀请。他们可能没有意识到
std::list
的析构函数不是虚拟的,也没有意识到在某些情况下
MyClassList
的析构函数不会被调用

好吧,
typedef
只能做其名称所暗示的事情,而派生类可能是其基础的全面改造。因此,尽管就编译器而言,如果您将自己限制为“仅仅”派生(不添加任何成员或重写任何内容等),可能不会有太大的差异,但就代码的人类读者而言,可能会有很大的差异

有人可能会想,“当
typedef
足够时,为什么这是一个派生类?”?大多数人会认为一定有原因,所以你会让代码的未来维护者更难生活。另一方面,
typedef
,是一种非常特殊的工具,不会引发问题


虽然我们在维护的话题上,不要忘记,因为C++中的大多数东西,只要我们遵守纪律,不跨越这条线,“没有什么会出错”是对灾难的公开邀请。由于编译器不在那里阻止你,总有一天会有人越界。

已经提到了很多事情。然而,一件大事是:

从类型派生不会继承所有构造函数

如果有许多非默认构造函数,那么在继承时就不会有它们(必须将它们转发给基构造函数)

typedef没有这样的“问题”

现在,typedef不会生成唯一的typeid。如果您想要这样做,并且没有继承的开销或其他缺点,请查看boost:它有一个强大的typedef宏,可以生成唯一的typeid:


类型定义是别名,而类是新类型。 在第一种情况下,编译器只需将MyClassList替换为list。 在第二种情况下,MyClassList涉及生成默认构造函数、复制构造函数赋值运算符、析构函数,以及(在使用c++11的情况下)移动构造函数和移动赋值。 在默认情况下,由于MyClassList没有额外的功能,优化很可能会消除它们

注意:我发现“不建议使用非虚拟析构函数派生类”参数很弱。C++开发人员应该知道派生并不一定意味着多态性。未通过指向其基的指针删除的类不需要虚拟析构函数,就像未设计为通过基指针“调用”方法的类不要求该方法是虚拟的一样。 简单地说,如果析构函数不是虚拟的,不要在删除时将该类型视为“多态的”。 从这个意义上讲,析构函数与其他虚拟或非虚拟方法没有区别。
如果必须将此参数视为强参数,则不应派生所有没有“all virtual”方法的类

标准禁止使用不完整(前向声明的类型)作为标准容器的类型参数,因此您的第二个示例不正确。@Mark B您可能是对的,这使得如果不使用派生类,如果你正确地隔离了你的类型定义,那么额外的包含应该不会花费你太多(你已经不能转发declare
list
,因为它在
std
名称空间中)。
class MyClassList;
class MyClass;
typedef list<MyClass> MyClassList;