“是什么意思?”;“通用编程”;在c++;? < > C++中的泛型编程< /强>的意义是什么?

“是什么意思?”;“通用编程”;在c++;? < > C++中的泛型编程< /强>的意义是什么?,c++,C++,此外,我还试图弄清楚容器、迭代器以及它们的不同类型的含义。通用编程:几乎只涉及模板 容器:一个结构或类,它包含自己的数据和作用于该数据的方法 迭代器:它是指向某个内存地址的指针,您可以对其进行迭代(如数组) 如果以上任何一项错误,请纠正我。泛型编程意味着您不是在编写按原样编译的源代码,而是在编写源代码的“模板”,编译器在编译过程中将其转换为源代码。泛型编程最简单的例子是容器类,例如包含其他对象集合的数组、列表或映射。但泛型编程还有很多。在C++环境中(也叫做元编程< /强>),它意味着编写在编译

此外,我还试图弄清楚容器、迭代器以及它们的不同类型的含义。

通用编程:几乎只涉及模板

容器:一个结构或类,它包含自己的数据和作用于该数据的方法

迭代器:它是指向某个内存地址的指针,您可以对其进行迭代(如数组)


如果以上任何一项错误,请纠正我。

泛型编程意味着您不是在编写按原样编译的源代码,而是在编写源代码的“模板”,编译器在编译过程中将其转换为源代码。泛型编程最简单的例子是容器类,例如包含其他对象集合的数组、列表或映射。但泛型编程还有很多。在C++环境中(也叫做<强>元编程< /强>),它意味着编写在编译时进行评估的程序。

泛型编程的一个基本示例是容器模板:在像C++这样的静态类型语言中,您必须声明包含整数、浮点和其他类型的单独容器,或者处理指向“代码>空隙”的指针,从而丢失所有类型信息。模板是泛型编程的C++方式,通过定义类在您定义类时未指定一个或多个参数的类来利用此约束。稍后,当您实例该模板时,您会告诉编译器应该使用哪种类型从该模板创建类。例如:

template<typename T>
class MyContainer
{
    // Container that deals with an arbitrary type T
};

void main() 
{
    // Make MyContainer take just ints.
    MyContainer<int> intContainer;
}

在此C++示例中,我用类型<代码> int 立即启动<强>模板<强> qLIST。QList存储对象列表的容器类。在本例中,我们将使用它来存储整数

然后,我创建一个迭代器
I
遍历列表
myList.begin()
返回指向列表第一个元素的迭代器。我们可以将迭代器与指向列表最后一个元素之后的另一个迭代器进行比较。如果两个迭代器相同,我们就知道已经通过了最后一个元素。在循环中,我们通过使用
*i
访问元素来打印元素,并使用
i++
转到下一个元素

请注意,在本例中,
*
+
是重载运算符,由迭代器类重新实现。在没有运算符重载的编程语言中,可以有像
i.element()
i.next()
这样的方法执行相同的任务。重要的是要看到,
i
不是指针,而是一个完全模仿指针行为的类


迭代器的好处是什么?它们提供了访问容器类成员的统一方法,完全独立于容器类的内部实现方式。不管你想遍历一个列表、映射或树,迭代器类(应该)都是一样的。

< P>作为历史感兴趣的一个点,在模板之前出现的C++版本是“包含”预处理器宏的一部分,它可以扩展到类声明。因此,您可以为一个类创建一个通用模式(“模板”),当您将某些参数扩展到实际的类声明时,您可以通过将它们传递到宏中来改变它。 但是,预处理器宏不是类型安全的,有点笨拙,它们在C++代码中的使用由于这些原因而明显下降;C++采用了更多的通用模板作为语言元素,但是“通用”编程的术语仍然存在。“泛型”现在在其他编程语言中用作美化类型转换。 除此之外,这个问题已经得到了专业的回答。

Container

C++中,容器是一个允许存储对象的类。例如,标准库

std::vector
是一个可调整大小的数组,它存储某种类型T的对象。为了正式地被视为容器类,它必须公开某些功能,以便于通用编程。我可以引用C++标准中的精确要求,但是对于大多数容器类来说,容器类是标准库中的:“代码>向量<代码>,代码> >列表<代码>,<代码> map < /C> >代码>设置< /COD>和<代码> MultMAPP < /C> >代码> MultSuth

其中一个重要的要求是,它们必须允许迭代器访问

迭代器

迭代器在这里可以表示两种情况:它是设计模式的名称,但在C++中,它也是设计模式的特定表达式的名称。C++迭代器是一种允许使用指针式语法遍历元素序列的类型。 例如,如果您有一个数组

inta[10]
,则可以使用普通指针作为迭代器:

int* first = a; // create an iterator that points to the beginning of the array
++first; // make the iterator point to the second element
int i = *first; // get the value of the element pointed to by the iterator
int* last = a+10; //create an "end" iterator, one which points one past the end of the array
如果我有一个链表,比如
std::list l
,我也可以做同样的事情,尽管现在我的迭代器不再只是指针,而是一个专门用于
std::list
的类类型:

std::list<int>::iterator first = l.begin(); // create an iterator that points to the beginning of the list
++first; // make the iterator point to the second element
int i = *first; // get the value of the element pointed to by the iterator
std::list<int>::iterator last = l.end(); //create an "end" iterator, one which points one past the end of the list
虽然因为它包装了一个常规流,但它是一种更有限类型的迭代器(例如,您不能向后移动,这意味着并非以下所有算法都适用于流迭代器)

现在,给定这些迭代器类型中的任何一种,我们都可以使用所有设计用于迭代器的标准库算法

std::find(first, last, 4); // return the first iterator which equals 4 and which is located in the interval [first, last)
或者我们可以对序列进行排序(不适用于流迭代器):

或者如果我们写一个函数,它平方一个int,比如:

int square(int i) { return i * i; }
然后我们可以将其应用于整个序列:

// for every element in the range [first, last), apply the square function, and output the result into the sequence starting with first
std::transform(first, last, first, square);
这就是迭代器的优点:它们
std::find(first, last, 4); // return the first iterator which equals 4 and which is located in the interval [first, last)
std::sort(first, last);
int square(int i) { return i * i; }
// for every element in the range [first, last), apply the square function, and output the result into the sequence starting with first
std::transform(first, last, first, square);