Résumé des nouvelles fonctionnalités de C ++ 11

Nouvelles fonctionnalités de C ++ 11

  1. Le mot clé auto (C ++ 11) basé sur une plage pour la boucle (C ++ 11). Le pointeur nullptr (C ++ 11)
  2. Gestion dynamique de la mémoire C ++
  3. Tableau de conteneurs série forward_list;
  4. Héritage et polymorphisme: dérogation finale
  5. supprimer: ne pas générer la fonction membre par défaut
  6. default: force le compilateur à générer des fonctions membres par défaut
  7. Pointeurs intelligents: unique_ptr, shared_ptr, faible_ptr
  8. Conteneur associatif structuré par hachage: séries non ordonnées

Initialisation unifiée

La norme en C ++ 98 permet l'utilisation d'accolades {} pour définir une valeur initiale de liste uniforme pour les éléments du tableau

int array1[] = {1,2,3,4,5};
int array2[5] = {0};

Cela ne peut pas être initialisé pour les conteneurs vectoriels

vector<int> v{1,2,3,4,5};

Il ne peut pas être compilé, donc chaque fois que vous définissez un vecteur, vous devez d'abord le définir, puis utiliser une boucle pour lui attribuer une valeur initiale, ce qui est très gênant.
C ++ 11 étend la portée de la liste entre accolades (liste d'initialisation) pour la rendre disponible pour tous les types intégrés et les types définis par l'utilisateur. Lorsque vous utilisez la liste d'initialisation, vous pouvez ajouter un signe égal (=) Ne peut pas être ajouté .

Accolades de type intégré {} initialisation

	// 内置类型变量
	int x1 = { 10 };
	int x2{ 10 };
	int x3 = 1 + 2;
	int x4 = { 1 + 2 };
	int x5{ 1 + 2 };
	int x6{ x1 + x2 };
	// 数组
	int arr1[5] {1, 2, 3, 4, 5};
	int arr2[]{1, 2, 3, 4, 5};
	// 动态数组,在C++98中不支持
	int* arr3 = new int[5]{1, 2, 3, 4, 5};
	// 标准容器
	vector<int> v{ 1, 2, 3, 4, 5 };
	map<int, int> m{ { 1, 1 }, { 2, 2, }, { 3, 3 }, { 4, 4 } };

Initialisation d'une liste de types personnalisée unique

class Point
{
public:
	Point(int x = 0, int y = 0) 
		: _x(x), _y(y)
	{}
private:
	int _x;
	int _y;
};
int main()
{
	//两种初始化都可以
	Point p{ 1, 2 };
	Point p2(1, 2);
	return 0;
}

Initialisation de plusieurs listes de types personnalisés

Si vous souhaitez prendre en charge l'initialisation de liste pour plusieurs objets, vous devez ajouter un constructeur avec un paramètre de type initializer_list à la classe (classe de modèle) . Remarque: initializer_list est un modèle de classe défini par le système. Il existe trois méthodes principales dans ce modèle de classe: l'itérateur begin (), end () et la méthode size () pour obtenir le nombre d'éléments dans l'intervalle.

template<class T>
	class vector
	{
	public:
		vector()
			:_start(nullptr)
			, _finish(nullptr)
			, _endofstorage(nullptr)
		{}
		vector(initializer_list<T>l)
			:_start(new T[l.size()])
		{
			_finish = _start;
			for (auto e : l)
			{
				*_finish++ = e;
			}
		}
	private:
		T* _start;
		T* _finish;
		T* _endofstorage;
	};

Déduction de type variable

dérivation automatique

résumé automatique

déduction de type decltype

La condition préalable à l'utilisation de auto est: le type déclaré par auto doit être initialisé, sinon le compilateur ne peut pas dériver le type réel de auto

template<class T1,class T2>
//返回的时候,返回T1和T2都不行,应该返回T1+T2后的值的类型
auto Add(const T1& left, const T2& right)
{
	return left + right;
}

Si le type réel du résultat après addition peut être utilisé comme type de retour de la fonction, il n'y aura pas d'erreur, mais cela nécessite que le programme s'exécute pour connaître le
type réel du résultat , c'est-à-dire RTTI (Run-Time Type Identification).

  • typeidPeut uniquement afficher le type et ne pas définir le type avec sa classe de résultat
  • dynamic_castNe peut être utilisé que dans les systèmes d'héritage contenant des fonctions virtuelles
De nouveaux mots clés sont donc nécessaires

decltype est le type utilisé pour définir les variables en fonction du type réel de l'expression , par exemple: déduction du type de valeur de retour

//此处auto为占位符
//返回值类型追踪
auto  Add( T1& left,  T2& right)->decltype(left+right)
{
	return left + right;
	//ret = left + right;
}

int main()
{
	int a = 1;
	double b = 2.0;
	cout<< Add(a, b);
	return 0;
}

Gamme pour boucle

Gamme pour

dérogation finale

Résumée dans le polymorphisme

Pointeur intelligent

Résumé du pointeur intelligent

Nouveau tableau de conteneurs-tableau statique, liste_avant et séries non ordonnées

Constructeur délégué

Le soi-disant constructeur de délégation: fait référence à une méthode de construction de classe dans laquelle la fonction de délégation délègue la tâche construite au constructeur cible.
Le constructeur qui appelle la "version de base" dans la liste d'initialisation est appelé le constructeur délégué, et la "version de base" appelée est le constructeur cible.
Remarque: Le constructeur ne peut pas "déléguer" et utiliser la liste d'initialisation en même temps.

class Info {
public:
	Info() 
		: _type(0)
		, _name('a')
	{
		InitRSet();
	}
	Info(int type) 
		:Info()
		//不能再在初始化列表中初始化其它的成员变量
		//,_type(type)
	{
		//InitRSet();
		_type = type;
	}
	Info(char type) 
		:Info()
	{
		//InitRSet();
		_type = type;
	}
private:
	void InitRSet() 
	{
		//初始化其他变量
	}
private:
	int _type;
	char _name;
	//...
};
  • Le constructeur délégué peut également être le constructeur cible
  • N'oubliez pas: la délégation en anneau peut toujours être compilée mais débordera sur la pile de droite

Référence de valeur

Résumé des références rvalue

Contrôle de fonction par défaut

C ++ 11 permet aux programmeurs de contrôler si le compilateur doit générer les fonctions générées par défaut

Fonction par défaut explicite

En C ++ 11, vous pouvez ajouter = default à la définition ou à la déclaration de la fonction par défaut pour demander explicitement au compilateur de générer la version par défaut de la fonction . La =defaultfonction modifiée est appelée fonction par défaut explicite .

class A
{
public:
	A(int a): _a(a)
	{}
	// 显式缺省构造函数,由编译器生成
	A() = default;
	// 在类中声明,在类外定义时让编译器生成默认赋值运算符重载
	A& operator=(const A& a);
private:
	int _a;
};
	A& A::operator=(const A& a) = default;
int main()
{
	A a1(10);
	A a2;
	a2 = a1;
	return 0;
}

Supprimer la fonction par défaut

Si vous souhaitez limiter la génération de certaines fonctions par défaut, en C ++ 98, la fonction est définie sur privé et non défini, de sorte que si quelqu'un d'autre veut l'appeler, une erreur sera signalée. En C ++ 11, c'est plus simple. Il suffit d'ajouter = supprimer à la déclaration de fonction. Cette syntaxe indique au compilateur de ne pas générer la version par défaut de la fonction correspondante. La fonction modifiée par = supprimer est appelée fonction de suppression .

class A
{
public:
	A(int a): _a(a)
	{}
	// 禁止编译器生成默认的拷贝构造函数以及赋值运算符重载
	A(const A&) = delete;
	A& operator(const A&) = delete;
private:
	int _a;
};
int main()
{
	A a1(10);
	// 编译失败,因为该类没有拷贝构造函数
	//A a2(a1);
	// 编译失败,因为该类没有赋值运算符重载
	A a3(20);
	a3 = a2;
	return 0;
}

Remarque: Évitez d'utiliser la fonction de suppression avec explicite

Paramètre par défaut

Expression Lambda et bibliothèque de threads

Résumé des expressions lambda et des bibliothèques de threads
Publié 253 articles originaux · loué 41 · 40 000+ vues

Je suppose que tu aimes

Origine blog.csdn.net/liuyuchen282828/article/details/103954995
conseillé
Classement