在他的两本书中
C ++编程语言,2013(第4版)和 C ++之旅,2013
Bjarne Stroustrup写道:
类型,例如复杂... 被称为具体类型 ,因为 他们的陈述是他们定义的一部分。
以下内容在某种程度上澄清了上述陈述:
在这方面,它们类似于内置类型。相比之下,抽象类型 是一种完全隔离用户实现的类型 细节。为此,我们将接口与接口分离 表示并放弃真正的局部变量。既然我们没有 了解抽象类型的表示(甚至不知道) 它的大小),我们必须在免费商店分配对象并访问它们 通过引用或指针。
在短语" ...他们的陈述是他们定义的一部分。"
类型表示的含义是什么?也就是说,究竟是什么的表示:内存中的对象布局?该类型包含的私有和公共数据?或其他什么?
类型定义的含义是什么?
类型表示和定义的典型含义是否与C ++相关?
我决定做更多的研究,并检查了其他来源。首先,我查看了ISO / IEC 14882:2011规范,其中规定了C ++编程语言实现的要求,然后是其他来源。
我无法在ISO规范中找到类似"类型表示"或"表示类型"。相反,有两个与对象相关的术语:
类型为
T
的对象的对象表示是由{{{{}类型的对象占用的 Nunsigned char
个对象的序列1}},其中 N 等于T
。对象的值表示是保存类型
sizeof(T)
的值的位集。对于简单的可复制类型,值表示是对象表示中的一组位,用于确定值,该值是实现定义的值集的一个离散元素。
所以在我看来,术语类型表示在ISO标准中没有任何常规含义。
确定。也许它超出ISO标准?让我们看看是什么 Linux Standard Base C++ Specification 3.1 > Chapter 7. C++ Class Representations > 7.1. C++ Data Representation说:
由C ++程序的编译过程生成的目标文件应包含几个密切相关的内部对象或类组件,以表示每个C ++类。这些对象不是源代码的可见部分。下表以高级别描述了这些类组件。
表类组件
Object.......................Contains =----------------------------------------= Class Data...................Class members Virtual Table................Information needed to dispatch virtual functions, access virtual base class subobjects and to access the RTTI information RTTI.........................Run-Time Type Information used by the typeid and dynamic_cast operators, and exception handlers Typeinfo Name................String representation of Class name Construction Virtual Table...Information needed during construction and destruction of Classes with non-trivial inheritance relationships. VTT..........................A table of virtual table pointers which holds the addresses of construction and non-construction virtual tables.
我再次无法在ISO规范中找到类型定义的明确解释。
相反,我找到了以下内容:
声明可能会在翻译中引入一个或多个名称 unit ... 类声明将类名引入 声明的范围...... 声明是一种定义,除非 [我删除了与类声明没有直接关系的东西],... 这是一个班级名称声明 ......
以下是微软对同一事物的解释:
C++ Declarations - MSDN - Microsoft
声明介绍 一个或多个名字加入一个程序。声明可以发生多次 曾经在一个程序中... 声明也可以作为定义,除了 当声明:...; 是一个没有的类名声明 以下定义,例如T类; ...
和
C++ Definitions - MSDN - Microsoft
定义是唯一的 对象或变量,函数,类或的规范 枚举。因为定义必须是唯一的,所以程序可以包含 给定程序元素只有一个定义。 可以有一个 声明与定义之间的多对一关系。 有两种情况可以声明和未定义程序元素:声明了一个函数但从未引用过函数 函数调用或带有函数地址的表达式。 类仅以不需要其定义的方式使用 已知的。
示例:
T
候选答案N1:
Jonathan Wakely提出的
(以下是我的理解)
短语" 类型,例如复杂... 被称为具体类型,因为它们的表示是其定义的一部分"应按以下方式解释和理解:
●他们的(=类型)定义是一个技术c ++术语,其含义是常规的,可以在c ++规范中找到;
●他们的(=类型)表示(根据Jonathan Wakely所说)在这种情况下不是技术c ++术语,但任何懂英语的人都可以很容易地理解其含义(可能,这是我的猜测,之前已经接触过大量的c ++代码和文本)。此上下文中的类型表示意味着
"定义类型是什么以及它做什么的属性",即:
"对于具体类型:其成员的类型和布局",
"对于抽象类型:其成员函数及其可观察行为"
●然后整个短语(我们谈论的具体类)转换为:
" 类型,例如复杂... 被称为具体类型,因为其成员的类型和布局是其定义的一部分"
我认为这种解释是有道理的,可以理解的,并且也与BS书中的内容很吻合。
如果此处的内容不合适,请纠正我**
答案 0 :(得分:2)
问题:在短语中......他们的表示是他们定义的一部分。“ 1)类型表示的含义是什么? (也就是说,WHAT的表示完全是:内存中的对象布局或类型所包含的私有和公共数据或其他内容)2)类型定义的含义是什么? 3)类型表示和定义的这些典型含义是否与c ++相关?
您要求Stroustrup在您引用的文字中不使用的术语含义!
他不是试图像C ++标准那样定义像“类型表示”这样的术语的正式规范,他正在撰写更为非正式的散文。您挖出的所有技术术语的引用都是误导性的,并不直接相关。
(也就是说,确切地表示WHAT:内存中的对象布局或类型包含的私有和公共数据或其他内容)
是的,你提到的两件事。对于具体类型,定义它是什么以及它的作用的属性包括其成员的类型和布局。即如何在源代码中表示。
对于抽象类,定义它是什么以及它做什么的属性是它的成员函数和它们的可观察行为。它如何产生可观察行为的细节不一定重要,有时在源代码中甚至不可见,因为你实际上使用了另一段代码中定义的一些具体类,只能通过抽象接口使用它。
编辑:根据您在下面写的评论判断,您显然错过了我试图给您答案的答案。我上面写的内容是指定义类型是什么以及它做什么的属性。这是“类型的定义”。
如果您必须为用户编写C ++类型的文档,您将如何定义它?
对于具体类型,您可以描述其成员的类型,从而根据其成员的属性定义其某些属性。例如“A std::complex<float>
存储两个float
成员,代表复数的实部和虚部。”这告诉您std::complex<float>
只能存储与float
具有相同精度的复数,即其精度取决于使用两个float
成员表示的事实。
对于抽象类,您将描述其成员函数的行为(可能是virtual
),因此您可以根据其所遵循的接口来描述它,而不是根据其实现的细节来描述它。
但它们不是正式条款,我认为将它们视为严格的技术术语是错误的。他只是用他们惯用的英语含义。
答案 1 :(得分:1)
你今晚要去看晚餐vegetable
。等一下......蔬菜? “蔬菜”这个词确定了一些东西,但它没有任何代表性。有人肯定会问你哪种蔬菜。因此,蔬菜是一种抽象概念。
现在您订购了一些potatoes
和onions
。好吧,他们定义一些属性,代表本身就足够了,这样你就可以在商店中找到。土豆和洋葱弥补了具有明确属性和行为的类型的具体表示。
尝试按照这个类比编写两个类。您可以连接到representation is part of their definition.
答案 2 :(得分:0)
我偶然发现了文本中的同一段落,花了我一段时间,但我相信我从文本中推导出了 representation 和 definition 的含义。一个班级。
问题1的答案:类型的表示形式是数据成员。这些是存储信息/状态的类型的成员,而不是存储在其中的方法/操作。
问题2的答案: 定义只是实现该类的代码。 (例如下面的Vector
的定义)。
理论上:请参见同一本书的第2.3.2节,并密切注意“表示”一词的使用:
将数据与操作分开指定具有优点,例如能够以任意方式使用数据。但是,表示和操作之间需要更紧密的联系,以使用户定义的类型具有“真实类型”所期望的所有属性。
似乎这里的“表示形式”现在代替了“数据”。
在这里,向量(成员elem和sz)的表示形式 [...]
elem和sz正是该部分中定义的Vector类的数据成员:
class Vector {
public:
Vector(int s) :elem{new double[s]}, sz{s} {} // construct a Vector
double& operator[](int i) { return elem[i]; } // element access: subscripting
int size() { return sz; }
private:
double* elem; // pointer to the elements
int sz; // the number of elements
};
进一步的说明:
对于具体类型,可以从定义中得知必须为该类型的对象的数据成员分配多少内存。当您在程序的源代码中某处声明一个该类型的变量时,编译器将知道其在内存中的大小。
在上面定义的类Vector
的情况下,该类的实例的数据成员所需的内存将是整数sz
和双精度{{1 }}。
elem
没有数据成员(进一步支持我对问题1的回答)。
考虑到这一点,在有疑问的句子后面的一些说明中,使用了 definition 和 representation 一词是有意义的。 我将解释: 由于表示形式是具体类型定义的一部分,因此我们可以将这种类型的对象放在堆栈,静态分配的内存和其他对象中,并且可以直接引用此类对象,而无需使用指针或引用等。 如果我们不知道对象的数据成员的大小,那么我们将无法执行这些操作。
针对问题3: 我不知道第3个问题的答案,但我相信,如先前的回答所述,此处使用的术语是非正式的,不应视为某种标准。这与本书所写部分的精神相吻合,在本书的一部分中,它只是对C ++进行了简要的高层非正式概述,而不假定以前的知识,因此避免了行话。