C ++:エッセイ9-テンプレート/インライン関数/コンテナ

C ++設計パラダイム:(これまでに2つのC ++設計パラダイムを学びました)

(1)プロセス指向:プロセス指向のパラダイムに従って、プログラムをさまざまな機能に分割します。

(2)オブジェクト指向:オブジェクト指向のパラダイムに従ってコードとデータをさまざまなクラスに編成し、クラス間の継承関係を確立します。

別のパラダイム:パラダイムプログラミング。

(3)汎用プログラミング:汎用プログラミングテクノロジは、プログラマが特定の関数やクラスではなく、関数やクラスの青写真(つまり、テンプレート、テンプレート)を作成することをサポートします。

 
PS:キーワードクラスは、これがクラスであることを意味するのではなく、単なる従来の書き方です。Tがタイプであることをコンピュータに伝えた後、通常のデータタイプのように使用できます。(書き込み方法は、最初にtemplate <class T>を書き込み、次に使用する関数テンプレートのプロトタイプを書き込むことです)

2つのアドレスaとbの交換を実現するため、つまり、で渡された2つのパラメーター値の交換を実現するため。

 

例:(関数テンプレート)

#include<iostream>
#include<string>

template<class T>
void swap(T &a,T &b)
{
    T tmp=a;//设置一个中间变量
    a=b;
    b=tmp;
}
int main()
{   
    int i1=3;
    int i2=4;
    std::cout<<“交换前i1=”<<i1<",i2="<<i2<<std::endl;
    swap(i1,i2);//这种是传引用调用,我们传给他i1,i2,用一个&指针去引用他i1的地址
    std::cout<<“交换后i1=”<<i1<",i2="<<i2<<std::endl;

    std::string1 s1="我们";
    std::string2 s2=“他们”;
    std::cout<<“交换前s1=”<<s1<",s2="<<s2<<std::endl;
    swap(s1,s2);//这种是传引用调用,我们传给他i1,i2,用一个&指针去引用他i1的地址
    std::cout<<“交换后s1=”<<s1<",s2="<<s2<<std::endl;
    return 0;
}

PS:  

彼が型を呼び出すプロセスで使用する値の型はすでにわかっているので、それがint整数型の場合は、<>山括弧内にintを書き込み、double型の場合は、<>山括弧内にdoubleを書き込みます。ただし、従来の方法で記述したい場合は、通常の関数呼び出しのように2つの山括弧を記述しなくてもかまいません。ただし、関数テンプレートを呼び出すことを強調すると、次のようなデータタイプで<>山括弧を追加できます。

---------クラステンプレート:(クラスは高度なものに関連しています)

 特定の操作はTを置き換えます。ここで、Tは単なるプレースホルダーです。

スタック:スタックは、挿入と削除の操作をテーブルの一方の端のみに制限する線形テーブルです。通常、挿入と削除の一方の端はスタックの最上位と呼ばれ、もう一方の端はスタックの最下部と呼ばれます。テーブルに要素がない場合これは空のスタックと呼ばれます。

たとえば、関数またはメソッドを呼び出すときは常に、コンパイラはスタックを使用して入力パラメータを渡します。最初に戻り値をプッシュし、次にパラメータをプッシュします。

  

クラステンプレートの方法でスタックプログラムを作成します。

#include<iostream>
#include<string>
template<class T>//定义一个类模板
class Stack
{
public:
	Stack(unsigned int size = 1000);//构造函数(最好给他一个参数)
	~Stack();//析构函数
	void push(T value);//方法(是把一个value给推进栈)//value是作为push的一个参数,不需要把他作为一个成员
	T pop();//(把栈里边的数据给推出来,不需要参数,但是需要返回值,不知道类型用T占位符)
private:
	unsigned int size;//私有成员,表示栈的尺寸
	unsigned int sp;//sp是栈指针(比如说我push进去了两个,要知道我现在push进去的元素在栈的第几个,要知道他的sp这个值指向的是哪一个,它指向b那我们就知道这个c是在b之上的,因为有这个指针才知道现在的状态)
	T *data;//栈的数据(data存放栈的数据)
};
//下面是对类的实现
template<class T>
Stack<T>::Stack(unsigned int size)//实现构造器(传进去参数size如果没有值就默认为100)
{
	this->size = size;//this->size就是类的成员中的size。后边的size就是传进来的参数size。用来表示我们这个栈有多大
	data = new T(size);//对栈进行初始化。我们就用new指针,new一个T类型,我们不知道是什么类型,在实际的调用过程中才知道,我们在整个模板类的整个声明和定义中都用T占位符来表示一种类型,虽然不知道它的类型是什么,但是我们知道它的大小是size。
	sp = 0;//sp默认是0
}
template<class T>
Stack<T>::~Stack()//析构器
{
	delete[]data;//析构器就是删除内存,这里是删除数组(动态的删除数组)
}
template <class T>
void Stack<T>::push(T value)
{
	data[sp++] = value;//0存放完之后再++
}
template<class T>
T Stack<T>::pop()//他的返回值是T,就是将当前sp指针,指向的这个栈的数据给弹回来(先--再sp)
{
	return data[--sp];//data是一个数组
}
int main()
{
	Stack<int> intStack(100);
	intStack.push(1);
	intStack.push(2);
	intStack.push(3);//推123进去
	std::cout << intStack.pop() << std::endl;
	std::cout << intStack.pop() << std::endl;
	std::cout << intStack.pop() << std::endl;//打印出来是321
	return 0;
}

結果を右上図に示します。

---------インライン関数とインラインテンプレートの作成

これはマクロ置換に似ており、関数の本体を呼び出される関数の名前に置き換えます。つまり、関数は3つの関数ABCに分割され、メイン関数が呼び出されます。Aがインライン関数の場合、通常の呼び出し関数では呼び出さず、A関数全体をメイン関数に入れて呼び出します。この場所、ソースコードに入れてください。

 

 

上記のプログラムを書き直してください:(クラスのインライン、私たちは彼のためにそれを書き込みます、インラインを追加する必要はありません)

#include<iostream>
#include<string>
template<class T>//定义一个类模板
class Stack
{
public:
	Stack(unsigned int size = 1000)//构造函数(最好给他一个参数)
	{
		this->size = size;
		data = new T(size);
		sp = 0;
	}
	~Stack()//析构函数
	{
		delete[]data;
	}
	void push(T value)
	{
		data[sp++] = value;//0存放完之后再++
	}
	T pop()
	{
		return data[--sp];//data是一个数组
	}
private:
	unsigned int size;
	unsigned int sp;
	T *data;
};
int main()
{
	Stack<int> intStack(100);
	intStack.push(1);
	intStack.push(2);
	intStack.push(3);//推123进去
	std::cout << intStack.pop() << std::endl;
	std::cout << intStack.pop() << std::endl;
	std::cout << intStack.pop() << std::endl;//打印出来是321
	return 0;
}

結果は上記と同じです。(前の部分は従来のパラダイムに従って記述されていますが、クラスのテンプレートをインラインで使用し、定義プロセスを直接記述することをお勧めします)

 

--------容器

テンプレートに基づく上記のスタッククラスはコンテナであり、スタックコンテナです。

 

 

例:

#include<iostream>
#include<string>
#include<vector>
int main()
{ 
	std::vector < std::string > names;//把这个向量vector的名字叫做names
	names.push_back("我");//往里边添加成员
	names.push_back("你");

	for (int i = 0; i < names.size(); i++)//知道他有多少个元素我们调用它的size()方法就可以了
	{
		std::cout << names[i] << std::endl;//可以使用像数组的方式来对它进行访问
	}
	return 0;
}

--------イテレーター

  

イテレーターを使用して、対応するトラバーサルを完了します。

#include<iostream>
#include<string>
#include<vector>
int main()
{ 
	std::vector < std::string > names;//把这个向量vector的名字叫做names
	names.push_back("我");//往里边添加成员
	names.push_back("你");
	//每一个容器里边都会提供一个迭代器,迭代器的名字都一样iterator
	//begin指向的是数据的起始位置,end是指向的是它最后一个元素的下一个位置,也就是他这个容器的底步
	std::vector<std::string>::iterator iter = names.begin();//定义一个叫iter的迭代器,begin()就是他的开始位置(这里就是对申请的iter这个迭代器进行初始化,初始化我们调用了这个向量的begin方法,这个方法是返回他的开始位置的值)
	//使用一个while循环
	while (iter != names.end())//注意while的条件(names.end()是向量的最后一个元素的下一个位置,是他的底步(指向最下一个元素的底步(不是指向最下面的一个元素)))
	{
		std::cout << *iter << std::endl;//这个迭代器是一个智能指针,一个特殊的指针我们用*取他的值
		++iter;//然后++指向下一个元素
	}
	return 0;

}

Sort();関数

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
int main()
{ 
	std::vector < std::string > names;//把这个向量vector的名字叫做names
	names.push_back("I");
	names.push_back("we");//往里边添加成员
	names.push_back("you");
	names.push_back("he");
	names.push_back("she");
	std::sort(names.begin(), names.end());//排序
	
	std::vector<std::string>::iterator iter = names.begin();
	while (iter != names.end())
	{
		std::cout << *iter << std::endl;
		++iter;
	}
	return 0;

}

 

おすすめ

転載: blog.csdn.net/m0_37957160/article/details/109065956