c ++中"泛型编程"的含义是什么?

bun*_*nty 54 c++

c ++ 中泛型编程的含义是什么?

此外,我试图找出容器,迭代器和它们的不同类型的含义.

Wol*_*ngP 57

通用编程意味着您不是编写按原样编译的源代码,而是编写源代码的"模板",编译器在编译过程中将其转换为源代码.泛型编程的最简单示例是容器类,如包含其他对象集合的数组,列表或映射.但通用编程还有很多.在C++(并称为元编程)的上下文中,它意味着编写在编译时评估的程序.

泛型编程的一个基本示例是容器模板:在像C++这样的静态类型语言中,您必须声明包含整数,浮点数和其他类型的单独容器,或处理指针void并因此丢失所有类型信息.作为通用编程的C++方式的模板通过允许您定义在定义类时未指定一个或多个参数的类来利用此约束.当您稍后实例化模板时,您告诉编译器应该使用哪种类型来创建模板中的类.例:

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

void main() 
{
    // Make MyContainer take just ints.
    MyContainer<int> intContainer;
}
Run Code Online (Sandbox Code Playgroud)

模板是通用的,因为编译器将模板转换为实际代码.需要注意的是,在情况下,你不要实例模板没有代码会为它生成在所有.另一方面,如果你声明a MyContainer<int>,a MyContainer<float>和a MyContainer<String>,编译器将创建三个版本的代码,每个版本都有不同的类型.将涉及一些优化,但基本上您的模板代码将实例化为三种新类型.

迭代器是一种设计模式,在Gamma等人的开创性着作"设计模式"中得到了普及.这是迭代容器类内容的模式.与使用for-loop 不同,迭代器是指向容器成员的类的实例,它为您提供了一个统一的接口来遍历容器以及访问成员.看看这个例子:

// Instanciate template QList with type int
QList<int> myList;

// put some ints into myList

// Copyconstruct iterator that points to the
// first member of the list.
QList<int>::iterator i = myList.begin();

// Iterate through the list 
while (i != myList.end()) {
  std::cout << *i << std::endl;
  i++;
}
Run Code Online (Sandbox Code Playgroud)

在这个C++示例中,我正在使用类型即时消息模板 QList int.QList一个存储对象列表的容器类.在这个例子中,我们将使用它来存储整数.

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

请注意,在此示例中*,它++是重载的运算符,并由迭代器类重新实现.在没有运算符重载的编程语言中,可能存在类似i.element()i.next()执行相同任务的方法.重要的是要看到它i不是一个指针,而只是一个模仿指针行为的整个类.

迭代器有什么好处?它们提供了一种访问容器类成员的统一方法,完全不考虑容器类在内部的实现方式.无论你想要遍历列表,映射还是树,迭代器类(应该)总是以相同的方式工作.

  • 我不完全同意.泛型编程是它自己的范例,模板是在C++中实现它们的一种方式.正如Go所证明的那样,泛型编程并不意味着元编程. (2认同)

jal*_*alf 13

容器

在C++中,容器是一个允许您存储对象的类.例如,标准库std::vector<T>是一个可调整大小的数组,它存储某种类型T的对象.为了正式地被认为是容器类,它必须暴露某些功能以便于通用编程.我可以引述来自C++标准的具体要求,但对于大多数的目的,是重要的容器类是标准库中的那些:vector,deque,list,map,setmultimap/ multiset.

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

迭代器

"迭代器"在这里意味着两件事:它是设计模式的名称,但在C++中,它也是该设计模式的特定表达式的名称.C++迭代器是一种允许使用类似指针的语法遍历一系列元素的类型.

例如,如果您有一个数组int a[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
Run Code Online (Sandbox Code Playgroud)

如果我有一个链表,比如std::list<int> 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
Run Code Online (Sandbox Code Playgroud)

或者用向量std::vector<int> v:

std::vector<int>::iterator first = v.begin(); // create an iterator that points to the beginning of the vector
++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 = v.end(); //create an "end" iterator, one which points one past the end of the vector
Run Code Online (Sandbox Code Playgroud)

关于迭代器最重要的是,他们给我们一个统一的语法遍历元素序列,无论顺序如何存储在内存中(或者甚至如果它被存储在内存中.迭代器可以写遍历的内容磁盘上的数据库.或者我们可以使用迭代器包装器来创建流,例如std::cin看起来像一系列对象:

std::istream_iterator<int>(std::cin) first;
    ++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; //create an "end" iterator, which marks the end of the stream
Run Code Online (Sandbox Code Playgroud)

虽然因为它包装了一个常规流,但它是一种更有限的迭代器类型(例如,你无法向后移动,这意味着并非以下所有算法都适用于流迭代器.

现在,给定任何这些迭代器类型,我们可以使用所有旨在与迭代器一起使用的标准库算法.例如,要使用值查找序列中的第一个元素4:

std::find(first, last, 4); // return the first iterator which equals 4 and which is located in the interval [first, last)
Run Code Online (Sandbox Code Playgroud)

或者我们可以对序列进行排序(不适用于流迭代器):

std::sort(first, last);
Run Code Online (Sandbox Code Playgroud)

或者如果我们编写一个对int求平方的函数,例如:

int square(int i) { return i * i; }
Run Code Online (Sandbox Code Playgroud)

然后我们可以将它应用于整个序列:

// 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);
Run Code Online (Sandbox Code Playgroud)

这是迭代器的优点:它们抽象出容器的细节,以便我们可以对任何序列应用泛型操作.感谢迭代器,相同findsort实现与链表和数组一起使用,甚至与您自己的自制容器类一起使用.

通用编程

通用编程基本上是您的代码应尽可能通用的想法.如上面的迭代器示例所示,我们提出了一个通用的函数集,类型必须支持这些函数才能被称为迭代器,然后我们编写适用于任何迭代器类型的算法.

与传统的面向对象编程相比,迭代器必须通过继承某种IIterator接口来"证明"它们是迭代器.这会阻止我们使用原始指针作为迭代器,因此我们会失去通用性.

在C++中,通用编程,我们不需要官方接口.我们只是使用模板编写算法,因此它们接受任何恰好看起来像迭代器的类型,无论它们在何处,何时以及如何定义,以及它们是否来自公共基类或接口.


cse*_*eav 7

在最简单的定义中,泛型编程是一种计算机编程风格,其中算法是根据待指定的后续类型编写的,然后在需要时将特定类型作为参数进行实例化.

  • 你刚才解释了为什么我的答案很简短 (6认同)