模板和容器

2023-11-06

1. 什么是模板
模板定义:模板就是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数,从而实现了真正的代码可重用性。
我们知道,C++ 是一种“强类型”的语言,也就是说一个变量,编译器必须确切的知道它的类型,而模板就是构建在这个强类型语言基础上的泛型系统。
2. 模板的语法

模板函数
template < typename {类型参数名称}, [ int {Name}=...][, ...] > {函数定义}
模板类
template < typename ... , [ int {Name}=...] >   class ...
模板的参数可以是类型,或者是一个 int 型的值(或者可以转换为int 型的,比如 bool)。
3. 模板的使用--模板库只能通过头文件库的形式来提供

显式类型参数
对于模板函数,在函数名后添加 < {类型参数表} >。 例如:int z=max <int> ( x, y );
对于模板类,在类后添加 < {类型参数表} >

隐式类型参数:对于模板函数,如果类型参数可以推导,那么可以省略类型参数表,举个例子:
template < typename T >
T max( T a, T b )
{
return a < b ? b : a;
}
这个 max 函数就是一个模板函数,它可以传入一个 “类型”的参数,以便实现任意类型求最大值的效果。假设我们这样使用它:
int x=5, y=10;
int z=max <int>( x, y );
这时候发生了什么呢?我们传入的“类型参数”是int,因此编译器在编译这段代码时会使用 int 来构造一个新函数:
int max( int a, int b )
{
return a < b ? b : a;
}
后面的事就和编译普通的函数一样了,C++编译器继续使用强类型系统编译这个函数,由强类型系统来检查这个函数是否正确。

这个过程叫做模板的“特化”,它发生在编译期,当编译器发现模板函数、模板类被使用(注意,不是定义)的时候进行的。这个系统实际上比较像宏,但是比宏更为智能。 很明显,编译器必须知道模板如何特化这个函数,因此模板函数的实现,必须在“使用点”之前,因此模板库只能通过头文件库的形式来提供

//更为准确的解释 C++ Primer 3 10.5

C++支持两种模板编译模式包含模式Inclusion Model 和分离模式Separation Mode。

包含模式: 像内联函数那样将模板的说明和定义全部放在头文件中.

分离模式:将模板说明放在头文件中,但是将模板实现放在c文件中,但是需要加"export"关键字,告诉编译器在生成被其他文件使用的函数模板实例时可能需要这个模板定义。

可见使用包含模式比较简洁,所以推荐使用包含模式,将模板的说明和定义全部放在头文件中发布。除非出于软件商业化目的,不希望暴露模板定义代码给用户,需要采用分离模式。

4. 模板的类型推导-根据用户传送过来的行参推导
对于函数,编译器是知道传入参数的类型的,比如上面的max,max < ? >( x, y ),由于第一个参数 x 是 int 类型的,那么 ? 这里需要填写什么呢? 我们可以很明显的推断出应该是 "int",否则,后面的强类型系统将无法编译这个函数。编译器同样知道 x 的类型,因此它也能推导出“类型参数”,这时候我们调用时就可省略模板参数了。

这个推导是按顺序来的,因此如果上面的 y 是其他类型,? 仍然会被推导为 int,如果y无法隐性转换为int,强类型编译时就会报错。
5. 类型推导的隐式类型转换
在决定模板参数类型前,编译器执行下列隐式类型转换:
左值变换
修饰字转换
派生类到基类的转换
见《C++ Primer》([注2],P500)对此主题的完备讨论。
简而言之,编译器削弱了某些类型属性,例如我们例子中的引用类型的左值属性。举例来说,编译器用值类型实例化函数模板,而不是用相应的引用类型。
同样地,它用指针类型实例化函数模板,而不是相应的数组类型。
它去除const修饰,绝不会用const类型实例化函数模板,总是用相应的非const类型,不过对于指针来说,指针和 const 指针是不同的类型。
底线是:自动模板参数推导包含类型转换,并且在编译器自动决定模板参数时某些类型属性将丢失。这些类型属性可以在使用显式函数模板参数申明时得以保留。

6. 模板的实例化,特化

函数模板

实例化:函数模板指定了实际类型或值构造出独立的函数的过程,称为实例化,即模板的使用过程。模板的实例化可以通过隐式推导实现,也可以通过显示指定实现。

特化:我们并不总是能够写出对所有可能被实例化的类型都是最合适的函数模板在某些情况下,我们可能想利用类型的某些特性来编写一些比模板实例化的函数更高效的函数,这时,就为某种类型,显式定义模板的实现,成为显式特化,所以模板特还还是模板行为的定义过程。

#include <cstring>
// const char* 显式特化定义了max的字符串实现
typedef const char *PCC;
template<> PCC max< PCC >( PCC s1, PCC s2 )
{
return ( strcmp( s1, s2 ) > 0 ? s1 : s2 );
}

类模板

特化和部分特化

7. 仿函数
仿函数这个词经常会出现在模板库里(比如 STL),那么什么是仿函数呢?
顾名思义:仿函数就是能像函数一样工作的东西,请原谅我用东西这样一个代词,下面我会慢慢解释。
void dosome( int i )
这个 dosome 是一个函数,我们可以这样来使用它: dosome(5);
那么,有什么东西可以像这样工作么?

答案1:重载了 () 操作符的对象,比如:
struct DoSome
{
void operator()( int i );
}
DoSome dosome;
这里类(对 C++ 来说,struct 和类是相同的) 重载了 () 操作符,因此它的实例 dosome 可以这样用 dosome(5); 和上面的函数调用一模一样,不是么?所以 dosome 就是一个仿函数了。
实际上还有答案2:
函数指针指向的对象。
typedef void( *DoSomePtr )( int );
typedef void( DoSome )( int );
DoSomePtr *ptr=&func;
DoSome& dosome=*ptr;
dosome(5); // 这里又和函数调用一模一样了。
当然,答案3 成员函数指针指向的成员函数就是意料之中的答案了。
8. 仿函数的用处
不管是对象还是函数指针等等,它们都是可以被作为参数传递,或者被作为变量保存的。因此我们就可以把一个仿函数传递给一个函数,由这个函数根据需要来调用这个仿函数(有点类似回调)。
STL 模板库中,大量使用了这种技巧,来实现库的“灵活”。
比如:
for_each, 它的源代码大致如下:
template < typename Iterator, typename Functor >
void for_each( Iterator begin, Iterator end, Fucntor func )
{
for( ; begin!=end; begin++ )
func( *begin );
}
这个 for 循环遍历了容器中的每一个元素,对每个元素调用了仿函数 func,这样就实现了 对“每个元素做同样的事”这样一种编程的思想。
特别的,如果仿函数是一个对象,这个对象是可以有成员变量的,这就让 仿函数有了“状态”,从而实现了更高的灵活性。

模板用法:定义、使用 示例

#include <iostream>
using namespace std;

template < typename A, typename B>
class test
{
public:
     test();
     ~test();
     int gX();
};

template < typename A, typename B>
test< A, B >::test()
{
}

template < typename A, typename B>
test< A, B >::~test()
{
}

template < typename A, typename B>
int test< A, B >::gX()
{
    cout<< sizeof(A)<<endl;
    cout<< sizeof(B)<<endl;
    return 0;
}

int main ( void )
{
test<int,char> x;
x.gX();
return 0;
}

/List.h///

#include <iostream.h>
template<class T>
class List
{
public:
List();
~List();
void Add(T&);
                                void Remove(T&);
T* Find(T&);
void PrintList();
protected:
struct Node{
Node* pNext;
                                                T* pT;
};
Node* pFirst;
};
template<class T>
List<T>::List()
{
pFirst = 0;
}
template<class T>
void List<T>::Add(T& t)
{
Node* temp = new Node;
temp->pT = &t;
temp->pNext = pFirst;
pFirst = temp;
}
template<class T>
void List<T>::Remove(T& t)
{
Node* q = 0;
if(*(pFirst->pT) == t)
{
q = pFirst;
pFirst = pFirst->pNext;
}
                 else
    {
for(Node* p = pFirst;p->pNext;p = pNext)
if(*(p->pNext->pT) == t)
{
q = p->pNext;
p->pNext = q->pNext;
break;
}
}
if(q)
{
                                delete q->pT;
delete q;
}
}
template<class T>
T* List<T>::Find(T& t)
{
for(Node* p = pFirst;p;p = p->pNext)
{
if(*(p->pT) == t)
return p->pT;
}
return 0;
}
template<class T>
void List<T>::PrintList()
{
for(Node* p = pFirst;p;p = p->pNext)
{
cout<<*(p->pT)<<" ";
}
cout<<endl;
}
template<class T>
List<T>::~List()
{
Node* p;
while(p = pFirst)
{
pFirst = pFirst->pNext;
delete p->pT;
delete p;
}
}

///List. c//

#Include list.h

void main()
{
List<float>floatList;
for(int i = 1;i<7;i++)
{
floatList.Add(*new float(i+0.6));
}
floatList.PrintList();
float b = 3.6;
float* pa = floatList.Find(b);
if(pa)
floatList.Remove(*pa);
floatList.PrintList();
}

Visual C++的模板和泛型如何配合使用
本篇教程来源于 完全教程网 原文链接:http://www.pcstu.com/program/Cjj/jc/20071027/61279.html

我将演示模板和泛型在何种情况下能配合使用,在何种情况下不能配合使用,并指明在 Visual C++ 2005 下当前模板实现方式的缺陷,以此来结束这一系列有关在 Microsoft .NET Framework 中进行泛型编程的专栏。

我选择通过讨论将标准模板库 (STL) 引入 .NET 的过程中进行的工作,来介绍这份材料。首先,我将回顾 STL 的基本元素,这样所有人都将站在同一起跑线上。

STL 的 CAI
有三个主要元素可用于标准模板库的设计:容器、算法和迭代器 (CAI)。

顺序容器

STL 矢量vector 和 List 类表示顺序容器。顺序容器保存第一个元素、第二个元素等等,直到最后一个元素。用程序来表示的函数参数列表通常作为包含字符串类型的元素的矢量来实现。例如:
以下是引用片段:
vector paramlist;

关联容器

Map 和 Set 类表示关联容器。关联容器支持快速查找。例如,Map 表示键/值对:键用于查找,而值表示存储和检索的数据。要表示电话号码簿,您需要声明一个带有字符串键和整数值的 Map:
以下是引用片段:
map phonedir;
多重映射可使单一键支持多个电话条目。

泛型算法

STL 还提供一个算法集,其中包含用于查找、排序、替换和合并的算法(可以对容器进行运算)。这些算法称为泛型算法,因为它们独立于正在其上进行运算的元素类型(例如整型、双精度类型或字符串类型)和包含元素的容器类型(例如无论容器是矢量、列表还是内置数组)。
泛型算法通过直接在容器上进行运算来实现容器独立性。程序不向算法传递容器,而是向它们传递标记了要通过其进行迭代的元素范围的迭代器对 (第一个, 最后一个],其中最后一个元素充当终结标志或一个标记,以表明元素集之后的元素并将停止算法:
以下是引用片段:
sort( paramlist.begin(), paramlist.end() );
此处,begin() 和 end() 是所有 STL 容器提供的方法,会将迭代器返回到元素集第一个元素和位于末尾元素之后的元素。例如,看一下以下声明序列:

以下是引用片段:
void f()
{
int ia[4] = {21, 8, 5, 13 };
vector   ivec( ia, ia+4 );    //将 ivec 初始化为 ia...
list         ilist( ia, ia+4);            //将 ilist 初始化为 ia ...
// ...
}
注意:ia+4 实际指向最后一个元素 (13) 之后的地址。使用 STL 的人们最初可能被这种区别所蒙蔽,例如,传递截止到 ia+3 处,这将使元素 13 不能包括在一系列值中。

迭代器

迭代器提供了一种统一且独立于类型的方式来访问、遍历和比较容器的元素。迭代器是一种类抽象,可以提供统一的指针操作(例如 ++、--、*、==、!=),无论容器是内置数组、列表还是其他任何一致的 STL 容器:
以下是引用片段:
void f()
{
// 每次调用相同的泛型算法...
sort( ia, ia+4 );
sort( ivec.begin(), ivec.end() );
sort( ilist.begin(), ilist.end() );
}

在每个排序调用中(共三个),结果序列理所当然是:5、8、13、21(Fibonacci 序列的第四个到第七个元素)。
现在,这只是一种对 STL 的理想化观点,并不能证明在正式约束和实际约束下实际可行。正式约束是指:不是所有的容器类型均支持所有算法运算。例如,Map 或 Set 不支持 random_shuffle,因为对元素进行的任何重新排序均违反容器类型,这就像将索引编入堆栈中将违反堆栈的语义特征一样。

       更实际地说,通过泛型算法,使用排序或查找来获得 List 容器中的元素,比在矢量上进行同一运算更加费力。因此,List 容器类型提供了自己的比泛型算法更高效的类方法。同样,使用 List 容器类型的查找方法来查找 Map 元素,比使用查找算法(通过向算法传递 Map 的开始和结束迭代器及其键)更快捷。

大家可能会希望算法在所有容器上的执行效果都相同,但实际上,算法更适合在 Block 容器和内置数组,而不是在 List 容器和关联容器类型上使用。实际上,当我在 Bell 实验室与 Alex Stepanov 一起工作时,他就把泛型算法称为 Block 算法。

为 .NET 重新设计 STL
要将 STL 合并到 .NET 中,首先要将容器作为公共语言运行库 (CLR) 类型重新实现。出于多种原因,我在本文中不会进行深入的讨论。总之,最好使容器成为引用类而不是值类。例如:
以下是引用片段:
// 暂时简化声明...
template
ref class vector { ... };
template
ref class map { ... };

在本机 STL 中,所有容器都是非多态的。矢量的声明将给定实际矢量对象。示例如下:
以下是引用片段:
// 本机 STL 矢量
// ivec.empty() == true
// ivec.size() == 0
vector< int > ivec;
// ivec2.empty() == false
// ivec2.size() == 10
vector< int > ivec2( 10 );

但是在 C++/CLI 下声明引用类型时,将定义一个跟踪句柄(矢量本身位于托管的堆中)。默认情况下,句柄将设置为 nullptr。请查看图 1。

下一个设计要求是:使不支持模板的其他语言(例如 C# 和 Visual Basic?)能够使用容器。最简单的策略是:使模板容器实现一个或多个系统容器接口(分到两个命名空间中),如图 2 中所示。

通常,您将希望同时支持收集和泛型接口,以使当前使用收集接口的客户端能够使用您的类型。以下是声明支持两种接口的方法:
以下是引用片段:
template
ref class vector :
System::Collections::ICollection,
System::Collections::Generic::ICollection
{ ... };

要实现系统收集命名空间的容器接口,还必须实现 IEnumerator 和 IEnumerator 的实例:
以下是引用片段:
generic
ref class vector_enumerator :
System::Collections::IEnumerator,
System::Collections::Generic::IEnumerator
{ ... };

实现系统容器接口的弊端是:虽然使得元素可用,但是无法操作 STL/CLR 类型的容器。因此,额外的设计支持还应该提供泛型阴影容器类型,以使其他语言可以使用实际的容器类型。有两个常规策略可以实现这种支持:Plauger 方式和 Tsao 方式(以两个主要设计师 P. J. Plauger 和 Anson Tsao 的姓名来命名)。
可以认为 Plauger 方式提供泛型阴影类型。也就是说,您将创建阴影泛型类(可以将其称为 generic_vector)。它包含矢量模板的副本。示例如下:
以下是引用片段:
generic
public ref class vector_generic
{
vector^ m_templ; // 哎呀...
public:
vector_generic( vector^ );
};

m_templ 声明行上的“哎呀”注释表示在 .NET 下对模板使用的约束。由于存在这种约束,您不能以泛型类型存储要求实例化的模板。这是因为,两个参数化类型功能的实例化时间不同。泛型由运行时来实例化;而模板由编译器来实例化。因此,模板可以包含泛型,而泛型不能包含模板。

Plauger 方式下的解决方案为:创建一个公共泛型接口,模板和泛型均通过该接口派生。有关示例,请参阅图 3。Tsao 方式下的解决方案是根据以下事实得出的:接口始终为模板容器(在特定程序集中实例化)的引用。因此,您只需提供一个接口并实现模板即可。泛型阴影类型将被消除。
以下是引用片段:
generic
interface class vector_interface :ICollection {...};
template
ref class vector :vector_interface, ICollection {...};

在任何情况下,除了那些使用程序集的人们以外,所有人都可以执行泛型实例而不是 STL/CLR 容器。这是因为,C++/CLR 下的模板不能成为公共程序集成员。下一部分中讨论了此问题。

模板为非公共程序集类型
要使 .NET 识别类型,它需要两个元素:程序代码(表示要转换为公共中间语言 (CIL) 的类型)和元数据(描述类型的详细信息)。不幸的是,模板此时还不能通过任何一个元素提供给 .NET。与析构函数一样,模板并不是为 .NET 而存在的。
.NET 仅能识别模板的具体实例; 而不能识别出它们是一种模板。例如,.NET 可以识别 vector 和 vector 的 CIL 和元数据,但是不能识别共享的模板矢量,CIL 和元数据都是该模板矢量的实例。这种不可识别性的副作用是,您不能辨别模板。也就是说,您不能询问 vector 实例:“您是模板吗?如果是,请把您的参数列表和类定义传递给我好吗?”
另一方面,泛型在 CLR 2.0 中直接支持 CIL,并且具有完全支持泛型反射的扩展反射命名空间。这是您在选择设计方式(在应用程序中使用模板还是泛型类型)时,应该考虑的一个方面。还应考虑是否需要跨程序集共享。模板不能跨程序集共享,而泛型可以。因此,如果跨程序集共享对您的设计非常重要,则应选择泛型类而不是模板类。否则,您将需要提供某种形式的公共接口,来实现跨程序集的共享,正如我所介绍的有关 STL/CLR 设计的内容。

模板不能跨程序集识别的原因是:.NET 具有一个包含其源的扩展类型概念。也就是说,在 .NET 下与在本机C++ 中不同,类型具有一个位置,在此位置名称可在共享的全局空间中自由浮动。这种全局名称混乱使得将各种组件合并到一个工作应用程序中非常困难。进一步的区别在于:命名空间将提供程序级别的解决方案,而为类型添加位置将提供程序集级别的解决方案。

也就是说,全局公共名称实际上由其程序集分配,从而避免在合并程序集时发生名称冲突。在 .NET 下,类型具有一个位置。这意味着,一个程序集的 vector 不会被识别为另一个程序集的相同 vector,因为类型已由单独的程序集名称标记。由于 CLR 提供的运行时实例化,泛型不会出现这种问题。

那么,既然存在这些约束,为什么我们还选择同时提供模板和 STL/CLR 呢?执行工作的C++ 程序员已建立起该库和现有代码体的专业知识。我们不仅希望提供现有代码的迁移路径,还希望提供现有专业知识的迁移路径。如果您以前在 C++ 编程过程中依靠 STL,则会感到在 .NET 下缺少 STL 是一种损失。而使用 STL/CLR 则不会这样。我后来听说,计划在 STL 完成后使其可以下载使用。

什么是模板、泛型(Generic)技术、STL,它们有什么关联

泛型技术是一种设计理念,是一种将具体数据类型参数化的思维模式;模板是实现这种理念的一个途径,一种方式; STL是标准模板库就是将各种函数用模板来实现的类库。

STL 容器,算法,迭代器 总结

一、容器
作为STL的最主要组成部分--容器,分为向量(vector),表(list),映射(map),多重映射(multimap), 集合(set),多重集合(multiset), 队列(queue), 双端队列(deque),堆栈(stack)。
容器 特性所在头文件
1向量vector--利用连续的内存空间存储
相当与数组,快速的访问随机的元素,快速的在末尾插入元素,但是在序列中间岁间的插入,删除元素要慢,而且如果一开始分配的空间不够的话,有一个重新分配更大空间,然后拷贝的性能开销。

<vector> 对于小数据存储,即对象所占空间不大的情况下选择vecotor比较合适,如若对象size较大,还是利用列表使用指针操作效率更高。
2列表list
list 容器是一个双向链表, 除了实际的数据, 每个元素维持着两个分别指向下一个和上一个链表元素的指针,(每个元素间用链表相连), 访问随机元素不如vector快,随机的插入元素比vector快,对每个元素分配空间,所以不存在空间不够,重新分配的情况。
<list>

3映射map

map 也叫关联数组associative array , 提供一个键/值对, 键用来索引, 而值用作被存储和检索的数据. map 中键/值对构成好比一个地址和电话号码以人名为键值,具有快速查找能力
<map>
多重集合multimap
比起映射,一个键可以对应多了值。具有快速查找能力
<map>

4集合set, 即一堆值的集合
与map相比, set 只是键的集合. 例如一个公司可能定义一个集合bad_checks 由在过去两年中有过不良账单的人名构成当只想知道一个值是会存在时set 是最合适的

另外, set内部元素唯一,用一棵平衡树结构来存储,因此遍历的时候就排序了,查找也比快的哦。但是它插入和删除操作的效率不高.

还有, set可以进行集合的各种操作(交并补等)
<set>
多重集合multiset
和集合基本相同,但可以支持重复元素具有快速查找能力
<set>

5队列queue
双队列,从前面或后面快速的插入与删除,直接访问任何元素
插入只可以在尾部进行,删除、检索和修改只允许从头部进行。按照先进先出的原则。
<queue>

双端队列deque
基本上与向量相同,唯一的不同是,其在序列头部插入和删除操作也具有常量时间复杂度
<deque>
6堆栈stack
堆栈是项的有限序列,并满足序列中被删除、检索和修改的项只能是最近插入序列的项。即按照后进先出的原则
<stack>
考虑到不同的实际需要,更主要的是效率的需要,我们可以选择不同的容器来实现我们的程序,以此达到我们提高性能的目的。这也是用好STL的一个难点,但这也是关键。
二、算法
算法部分主要由头文件<algorithm>,<numeric>和<functional>组成。<algorithm>是所有STL头文件中最大的一个,它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。

<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。

<functional>中则定义了一些模板类,用以声明函数对象。
STL的算法也是非常优秀的,它们大部分都是类属的,基本上都用到了C++的模板来实现,这样,很多相似的函数就不用自己写了,只要用函数模板就OK了。
我们使用算法的时候,要针对不同的容器,比如:对集合的查找,最好不要用通用函数find(),它对集合使用的时候,性能非常的差,最好用集合自带的find()函数,它针对了集合进行了优化,性能非常的高。
三、迭代器
它的具体实现在<itertator> 中,我们完全可以不管迭代器类是怎么实现的,大多数的时候,把它理解为指针是没有问题的(指针是迭代器的一个特例,它也属于迭代器),但是,决不能完全这么做。
迭代器功能(Abilities Of Iterator Gategories)
输入迭代器 Input iterator

向前读   Reads forward istream

输出迭代器 Output iterator

向前写    Writes forward     ostream,inserter
前向迭代器   Forward iterator
向前读写       Read and Writes forward
双向迭代器      Bidirectional iterator
向前向后读写   Read and Writes forward and      backward    list,set,multiset,map,multimap
随机迭代器      Random access iterator
随机读写        Read and Write with random
access        vector,deque,array,string

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模板和容器 的相关文章

  • R语言学习笔记:分析学生的考试成绩

    孩子上初中时拿到过全年级一次考试所有科目的考试成绩表 正好可以用于R语言的统计分析学习 为了不泄漏孩子的姓名 就用学号代替了 感兴趣可以下载测试数据进行练习 num class chn math eng phy chem politics
  • [原]Pro*C介绍-内嵌SQL

    Translate by Z Jingwei Document address http www db stanford edu ullman fcdb oracle or proc html Pro C介绍内嵌SQL 概要 Pro C语法
  • 调用拷贝构造函数的几种情况(附面试题)

    1 深拷贝和浅拷贝 拷贝构造函数的使用 有时候需要自己定义拷贝构造函数 以避免浅拷贝问题 在什么情况下需要用户自己定义拷贝构造函数 一般情况下 当类中成员有指针变量 类中有动态内存分配时常常需要用户自己定义拷贝构造函数 在什么情况下系统会调
  • 五. python面向对象(多态 和metaclass=abc.ABCMeta)

    一 多态 多肽 一种事物的多种形态 叫多肽 例如 动物 animal 猫 狗 animal py 文件 动物类 都有名字这个属性 和吃这个方法 class Animal object def init self name self name
  • 多线程系列之——事件内核对象

    所有内核对象里面事件内核对象是最简单的一个 它包括一个使用计数 还有两个布尔值 一个布尔值用来表示事件是手动重置事件还是自动重置事件 另一个布尔值表示当前是否处于触发状态 当一个手动重置事件被触发的时候 所有等待该事件的线程都能变成调度状态
  • Vc/MFC中自定义消息及其PostMessage触发使用

    http blog csdn net ztz0223 article details 2058402 http blog csdn net a8082649 article details 7733527 http bbs csdn net
  • C++工程师复习题

    一 auto ptr 类使用必须满足下列限制 1 不要使用 auto ptr 对象保存指向静态分配对象的指针 2 不要使用两个 auto ptrs 对象指向同一对象 3 不要使用 auto ptr 对象保存指向动态分配数组的指针 4 不要将
  • c/c++入门教程 - 1.基础c/c++ - 1.0 Visual Studio 2019安装环境搭建

    推荐视频课程 https www bilibili com video BV1et411b73Z p 2 已投币三连 b站果然是个学习的网站 本来是想在linux环境下运行QT 于是先学了几个月linux嵌入式驱动开发 后来发现太底层了 与
  • JNA模拟复杂的C类型——Java映射char*、int*、float*、double*

    文章目录 引言 Java Native Type Conversions Java和C基本类型指针对应关系 Pointer的具体用法 引言 最近项目在用Java调用C写的一些三方库 没办法直接调 用Java封装一下C的接口 这就少不了要用到
  • 大端模式和小端模式转化

    在工作中遇到一个问题 数据是以大端模式存储的 而机器是小端模式 必须进行转换 否则使用时会出问题 一 定义 大端模式 Big Endian 数据的高字节 保存在内存的低地址中 数据的低字节 保存在内存的高地址中 小端模式 Little En
  • C/C++ 引用作为函数的返回值

    语法 类型 函数名 形参列表 函数体 特别注意 1 引用作为函数的返回值时 必须在定义函数时在函数名前将 2 用引用作函数的返回值的最大的好处是在内存中不产生返回值的副本 代码来源 RUNOOB include
  • 使用QZXing生成并解析二维码

    QZxing 是对 zxing 的一个封装 用于在 Qt 程序中加入条形码和二维码识别的功能 这里就讲讲如何编译和使用这个库 前几年 QZXing 的代码是放到 sourceforge net 上的 现在迁移到了 github com 所以
  • 经典面试题之new和malloc的区别

    new和malloc的区别是C C 一道经典的面试题 我也遇到过几次 回答的都不是很好 今天特意整理了一下 0 属性 new delete是C 关键字 需要编译器支持 malloc free是库函数 需要头文件支持 1 参数 使用new操作
  • 如何学好C语言的数据结构与算法?

    C语言的数据结构与算法 难就难在链表 学会了链表 可能后面就一点都不难了 书籍推荐 数据结构与算法分析 C语言描述版 要深入学习的话可以选择这本书 因为针对链表的讲解是比较详细的 所以可以很快理解链表 跟着书上一点点实现基本操作 增删改查
  • Lua和C++交互总结(很详细)

    出处 http blog csdn net shun fzll article details 39120965 一 lua堆栈 要理解lua和c 交互 首先要理解lua堆栈 简单来说 Lua和C c 语言通信的主要方法是一个无处不在的虚拟
  • R----dplyr包介绍学习

    dplyr包 plyr包的替代者 专门面对数据框 将ddplyr转变为更易用的接口 gt 来自dplyr包的管道函数 其作用是将前一步的结果直接传参给下一步的函数 从而省略了中间的赋值步骤 可以大量减少内存中的对象 节省内存 可惜的是应用范
  • Trace Function Enter, Exit and Leave

    http developer nokia com community wiki Trace Function Enter Exit and Leave
  • C/C++编程:令人印象深刻的高级技巧案例

    C C 编程语言在软件开发领域有着悠久的历史 由于其高效 灵活和底层访问能力 至今仍然被广泛应用 本文将介绍一些在C C 编程中令人印象深刻的高级技巧 帮助读者提升编程水平 更加高效地使用这两种强大的编程语言 一 指针运算与内存管理 C C
  • C++ 字符串比较------strcmp函数和strncmp函数

    strcmp 函数原型 int strcmp const char str1 const char str2 功能 strcmp函数会按照字典顺序逐个比较两个字符串的字符 直到遇到不同的字符或者遇到字符串结束符 0 返回值 该函数返回值如下
  • Woocommerce:添加第二个电子邮件地址不起作用,除非收件人是管理员

    我尝试了多种方法来向 Woocommerce 电子邮件添加其他收件人 但它似乎仅适用于主要收件人是管理员的测试订单 这些是我尝试过的片段 如果订单的客户是管理员 则电子邮件将发送到这两个地址 如果订单包含客户电子邮件地址 则仅发送至该电子邮

随机推荐

  • markdown+CSDN+Typora+知乎+微信公众号最佳偷懒写作方法

    目录 markdown 思想 适用范畴 基本语法 重点语法 高级语法 Typora 补充工具 公式编辑 保存和导出 导入 定制化主题 图片拖拽 超链接 列表 LaTex 公式 表格 生成目录 编辑模式 导出与公众号 md与CSDN 导入 导
  • 用户留存分析—SQL

    SELECT log day 日期 count user id day0 新增数量 count user id day1 count user id day0 次日留存率 count user id day3 count user id d
  • 星罗棋布:关于VPS测试脚本集锦内容

    2021 09 25 更新 优化排版 引言 莫忧世事兼身事 须著人间比梦间 勿埋我心 当我们获得一个服务器后 会想知道它的性能如何 宝塔自带跑分的应用 但是测试的数据比较片面 所以就有了各种各样的测试脚本 勿埋我心带你了解一下有哪些常用的V
  • VMware安装win10系统的心路历程

    友情提示 尽量使用原版或别人用过的 很早之前使用VMware装过win2008和centos7 都是傻瓜安装 没想到这次安装win10一点都不傻瓜 软件版本 VMware Workstation 15 Pro 1 按照常识先下载iso文件
  • hive建表

    https blog csdn net wgyzzzz article details 107446435 一 hive建表语法 二 hive外部表 1 准备测试数据 放入虚拟机 data目录下 2 创建外部表 3 装载数据 4 查询tes
  • unity使用setTrigger需注意地方

    使用上可以参考另一篇文章 RPG游戏主角状态机 Trigger触发器 注意都是从Any State开始的 否则你在使用Aniamtor的Trigger参数触发时没反应
  • 网页开发基础常见html、css

    目录 HTML基础 一 段落 行内和换行标签 二 文本样式标签 三 表格标签 四 表单标签 五 多行文本标签 六 列表标签 七 超链接标签 八 图像标签 HTML基础 html语言基本格式 常用的HTML标签 一 段落 行内和换行标签 二
  • 我为什么不在乎人工智能

    有人听说我想创业 给我提出了一些 忽悠 的办法 他们说 既然你是程序语言专家 而现在人工智能 AI 又非常热 那你其实可以搞一个 自动编程系统 号称可以自动生成程序 取代程序员的工作 节省许许多多的人力支出 这样就可以趁着 AI 热 拉到投
  • 记录一下:使用 python -m SimpleHTTPServer 快速搭建http服务

    为什么80 的码农都做不了架构师 gt gt gt 在 Linux 服务器上或安装了 Python 的机器上 Python自带了一个WEB服务器 SimpleHTTPServer 我们可以很简单的使用 python m SimpleHTTP
  • WinForm显示3D图(Sharpgl)

    总述 Sharpgl是 NET平台的Opengl 可以用来绘画 展示3D图 本文将介绍如何显示SOlidWorks等软件制作的3D模型 安装Sharpgl 下载SharpGL vsix文件并点击安装 VS中就会有相应的项目出现了 之后创建工
  • C语言(Head First C)-7:数据结构与动态存储

    该系列文章系个人读书笔记及总结性内容 任何组织和个人不得转载进行商业活动 7 数据结构与动态存储 一个结构根本不够 本章内容 1 如何用结构指针吧自定义数据类型连接成复杂的大型数据结构 通过创建链表探索其中的基本原理 2 通过在堆上动态分配
  • Jmeter元件正则表达式提取Response headers的数据

    本文以cookie提取为例来介绍用正则表达式如何提取Response headers的数据 实际cookie的获取只需要一个cookies管理器即可 jmeter会自动获取cookie 如果是用正则表达式提取Response headers
  • 基于深度学习的推荐系统(一)

    本文主要介绍推荐系统基本概念以及基本的协同过滤算法原理 推荐系统 快速有效地从复杂的数据中获取有价值的信息成为大数据大战的关键难题 推荐系统根据用户需求与兴趣 通过推荐算法从海量数据中挖掘出用户感兴趣的项目 如信息 服务 物品 将结果以个性
  • 前端基础知识6

    谈谈你对语义化标签的理解 语义化标签就是具有语义的标签 它可以清晰地向我们展示它的作用和用途 清晰的代码结构 在页面没有css的情况下 也能够呈现出清晰的代码内容 有利于SEO 爬虫依赖标签来确定关键字的权重 因此可以和搜索引擎建立良好的沟
  • SpringBoot 2.2.5 使用@ID 避坑指南

    1 如果你的数据库中没有主键 在你指定 ID的时候这个指必须是唯一的而且不能为null 如果不唯一 你数据库有6个数据 选为主键的字段 distinc一下有2个 那么就会3 3的重复 如果为null 则映射出来的bean中有null
  • FastDFS-02-JavaAPI

    我是码赛客1024 本节我们来使用java调用FastDFS进行文件上传等操作 一 介绍 在上一章节 咱们搭建好了fastdfs服务器 并实现了基于命令的上传测试和web访问 本节 咱们使用Java来调用API实现上传文件到FastDFS
  • linux命令&和&&,

    在linux中 和 和 介绍如下 表示任务在后台执行 如要在后台运行redis server 则有 redis server 表示前一条命令执行成功时 才执行后一条命令 如 echo 1 echo 2 表示管道 上一条命令的输出 作为下一条
  • 全网唯一最全彻底删除VS及VS注册表!

    当我们不再需要vs或者vs ide出现问题 并且你的专业课老师不教的情况下 怎么样独自且快速的情况下卸载干净 需要重装时 发现总是卸载不干净 卸载重装后该存在的问题还是存在 没有因重装而解决 那么如何彻底的卸载vs不留残留 设备 HPZHA
  • android集成flutter No implementation found for method getDatabasesPath on channel com.tekartik.sqflite

    项目场景 原有android项目集成flutter 环境 flutter sdk 1 17 4 android studio 3 6 3 android sdk 29 问题描述 运行报错 Unhandled Exception Missin
  • 模板和容器

    1 什么是模板 模板定义 模板就是实现代码重用机制的一种工具 它可以实现类型参数化 即把类型定义为参数 从而实现了真正的代码可重用性 我们知道 C 是一种 强类型 的语言 也就是说一个变量 编译器必须确切的知道它的类型 而模板就是构建在这个