Not go with the wind but C++

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。

目录

问题的提出
友元函数
  1. 特点 
  2. 应用实例
友元类
  1. 如何判断是类的友元
  2. 被声明两个类的友元声明
  3. 作为一个类的函数又是另一个类的友元
问题的提出
友元函数
  1. 特点 
  2. 应用实例
友元类
  1. 如何判断是类的友元
  2. 被声明两个类的友元声明
  3. 作为一个类的函数又是另一个类的友元

展开

问题的提出

  我们已知道类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。

  为了解决上述问题,提出一种使用友元的方案。友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元函数
特点 

  友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样。

应用实例

  下面举一例子说明友元函数的应用。

  #include<iostream>

  class Point

  {

  public:

  Point(double xx, double yy) { x=xx; y=yy; }

  void Getxy();

  friend double Distance(Point &a, Point &b);

  private:

  double x, y;

  };

  void Point::Getxy()

  {

  cout<<"("<

  }

  double Distance(Point &a, Point &b)

  {

  double dx = a.x - b.x;

  double dy = a.y - b.y;

  return sqrt(dx*dx+dy*dy);

  }

  void main()

  {

  Point p1(3.0, 4.0), p2(6.0, 8.0);

  p1.Getxy();

  p2.Getxy();

  double d = Distance(p1, p2);

  cout<<"Distance is"<

  }

  说明:在该程序中的Point类中说明了一个友元函数Distance(),它在说明时前边加 friend关键字,标识它不是成员函数,而是友元函数。它的定义方法与普通函数定义一样,而不同于成员函数的定义,因为它不需要指出所属的类。但是,它可以引用类中的私有成员,函数体中a.x,b.x,a.y,b.y都是类的私有成员,它们是通过对象引用的。在调用友元函数时,也是同普通函数的调用一样,不要像成员函数那样调用。本例中,p1.Getxy()和p2.Getxy()这是成员函数的调用,要用对象来表示。而Distance(p1, p2)是友元函数的调用,它直接调用,不需要对象表示,它的参数是对象。(该程序的功能是已知两点坐标,求出两点的距离。)

友元类

  友元除了前面讲过的函数以外,友元还可以是类,即一个类可以作另一个类的友元。当一个类作为另一个类的友元时,这就意味着这个类的所有成员函数都是另一个类的友元函数。

  让我们回顾一下重载的等于操作符的定义它是为名字空间域中定义的

  String 类而提供的针对两个String 对象的等于操作符如下

  bool operator==( const String &str1, const String &str2 )

  {

  if ( str1.size() != str2.size() )

  return false;

  return strcmp( str1.c_str(), str2.c_str() ) ? false : true;

  }

  把这个定义与被定义为成员函数的操作符定义相比较

  bool String::operator==( const String &rhs ) const

  {

  if ( _size != rhs._size )

  return false;

  return strcmp( _string, rhs._string ) ? false : true;

  }

  你看到区别了吗?我们注意到必须要修改函数定义内部对于String 类私有数据成员的引用方式因为新的等于操作符是全局函数不是类成员函数它不能直接引用String 的私有数据成员它使用访问成员函数size()和c_str()来获得String 对象的大小以及底层的C 风格字符串;

  另外一种可能的实现是把全局等于操作符声明为String 类的友元friend 通过把函

  数或操作符声明为友元一个类可以授予这个函数或操作符访问其非公有成员的权利

  友元声明以关键字friend 开始它只能出现在类定义中因为友元不是授权类的成员

  所以它不受其所在类的声明区域public private 和protected 的影响这里我们选择把所

  有友元声明组织在一起并放在类头之后

  class String {

  friend bool operator==( const String &, const String & );

  friend bool operator==( const char *, const String & );

  friend bool operator==( const String &, const char * );

  public:

  // ... String 类中的其他部分

  };

  String 类中的三个友元声明把全局域中声明的三个重载的比较操作符在上节介绍声

  明为String 类的友元

  既然这些等于操作符已经被声明为友元那么它们的定义就可以直接引用String 的私有

  成员了

  // friend 操作符直接引用 String 的私有成员

  // friend operators: refer to String private members directly

  bool operator==( const String &str1, const String &str2 )

  {

  if ( str1._size != str2._size )

  return false;

  return strcmp( str1._string, str2._string ) ? false : true;

  }

  inline bool operator==( const String &str, const char *s )

  {

  return strcmp( str._string, s ) ? false : true;

  }

  // 以下略

如何判断是类的友元

  有人可能会说在这种情况下由于c_str()和size()是内联的它们提供了等价的效率

  并且保留了成员封装所以没必要直接访问_size 和_string 这是对的使用成员访问函数而

  不是直接访问成员并不总是意味着它的效率较低由于存在这些访问函数所以没有必要

  把等于操作符声明为String 类的友元

  那么我们怎样判断一个非类成员的操作符应该是类的友元还是应该使用成员访问函

  数呢一般来说类的实现者应该尽量使得名字空间函数和访问类内部表示的操作符的数目

  最小化如果已经提供了访问成员函数并且它们具有等同的效率那么最好是使用这些成员

  函数并且把名字空间操作符与类表示中的变化隔离开但是如果类的实现者决定不为该

  类的某些私有成员提供访问成员函数而且名字空间操作符需要引用这些私有成员才能完成

  它们的操作那么就必须使用友元机制

  友元声明的最常见用法是允许非成员的重载操作符访问一个视其为朋友的类的私

  有成员原因是除了提供左和右操作数的对称性外非成员的重载操作符就像成员函数一

  样能够完全访问一个类的私有成员

  虽然友元声明的主要用处是在重载操作符上但是在某些情况下一个名字空间函数

  另一个在此之前被定义的类的成员函数或者一个完整的类必须声明为友元在使一个类成

  为另一个类的友元时友元类的成员函数被赋予访问授权类的非公有成员的权利下面我们

  将更详细地了解函数而不是操作符的友元声明

  一个类必须把它希望与之建立友元关系的重载函数集中的每个函数都声明为友元

  例如

  extern ostream& storeOn( ostream &, Screen & );

  extern BitMap& storeOn( BitMap &, Screen & );

  // ...

  class Screen

  {

  friend ostream& storeOn( ostream &, Screen & );

  friend BitMap& storeOn( BitMap &, Screen & );

  // ...

  };

  如果一个函数操纵两个不同类类型的对象而且该函数需要访问这两个类的非公有成员

  则这个函数可以被声明为这两个类的友元或者作为一个类的成员函数并声明为另一个类

  的友元让我们来看一看怎样做

被声明两个类的友元声明

  如果我们决定一个函数必须被声明为两个类的友元则友元声明如下

  class Window; // 只声明

  class Screen {

  friend bool is_equal( Screen &, Window & );

  // ...

  };

  class Window {

  friend bool is_equal( Screen &, Window & );

  // ...

  };

作为一个类的函数又是另一个类的友元(成员函数做友元

  如果我们决定该函数必须作为一个类的成员函数并又是另一个类的友元则成员函数

  声明和友元声明如下

  class Window;

  class Screen {

  public:

  // copy 是类 Screen 的成员

  Screen& copy( Window & );

  // ...

  };

  class Window {

  // copy 是类 Window 的一个友元

  friend Screen& Screen::copy( Window & );

  // ...

  };

  只有当一个类的定义已经被看到时它的成员函数才能被声明为另一个类的友元(即一个类的成员函数被声明为友元的条件是,该类的定义必须在被声明为友元之前)这并

  不总是能够做到的例如如果Screen 类必须把Window 类的成员函数声明为友元而Window

  类必须把Screen 类的成员函数声明为友元该怎么办呢在这种情况下可以把整个Window

  类声明为Screen 类的友元例如

  class Window;

  class Screen {

  friend class Window;

  // ...

  };

  Screen 类的非公有成员现在可以被Window 的每个成员函数访问。



有以下这样3个求加法的函数: 

复制代码
 1 int Add(int x,int y)
2 {
3 return x+y;
4 }
5
6 double Add(double x,double y)
7 {
8 return x+y;
9 }
10
11 long Add(long x,long y)
12 {
13 return x+y;
14 }
复制代码

它们拥有同一个函数名,相同的函数体,却因为参数类型和返回值类型不一样,所以是3个完全不同的函数。即使它们是二元加法的重载函数,但是不得不为每一函数编写一组函数体完全相同的代码。如果从这些函数中提炼出一个通用函数,而它又适用于多种不同类型的数据,这样会使代码的重用率大大提高。那么C++的模板就可解决这样的问题。模板可以实现类型的参数化(把类型定义为参数),从而实现了真正的代码可重用性。C++中的模板可分为函数模板和类模板,而把函数模板的具体化称为模板函数,把类模板的具体化成为模板类。

  1.函数模板就是建立一个通用的函数,其参数类型和返回类型不具体指定,用一个虚拟的类型来代表。函数模板的声明格式:

  template<typename 类型参数>

  返回类型 函数名(模板形参表)

  {

    函数体

  }

  或

  template<class 类型参数>

  返回类型 函数名(模板形参表)

  {

    函数体

  }

template是一个声明模板的关键字,类型参数一般用T这样的标识符来代表一个虚拟的类型,当使用函数模板时,会将类型参数具体化。typename和class关键字作用都是用来表示它们之后的参数是一个类型的参数。只不过class是早期C++版本中所使用的,后来为了不与类产生混淆,所以增加个关键字typename。下面我就对上述3个加法函数进行函数模板化:

View Code
复制代码
 1 #include "stdafx.h"
2 #include <iostream>
3
4 template <typename T>//加法函数模板
5 T Add(T x,T y)
6 {
7 return x+y;
8 }
9
10 int main()
11 {
12
13 int x=10,y=10;
14 std::cout<<Add(x,y)<<std::endl;//相当于调用函数int Add(int,int)
15
16 double x1=10.10,y1=10.10;
17 std::cout<<Add(x1,y1)<<std::endl;//相当于调用函数double Add(double,double)
18
19 long x2=9999,y2=9999;
20 std::cout<<Add(x2,y2)<<std::endl;//相当于调用函数long Add(long,long)
21
22 return0;
23 }
复制代码

结果:

看着上述的代码中,是否觉得函数模板的声明和C#中的泛型使用有点相像呢,当调用函数模板时(如:Add(10,10))就是对函数模板的具体化(如:int Add(int,int)),具体化的函数模板就是模板函数。在函数模板中类型参数也可以指定多个,只不过定义的每个类型参数之前都必须有关键字typename(class)。

View Code
复制代码
 1 #include "stdafx.h"
2 #include <iostream>
3
4 template <typename T1,typename T2>//多类型参数的函数模板
5 T1 Add(T1 x,T2 y)
6 {
7 return x+y;
8 }
9
10 int main()
11 {
12 int x=10;
13 double y=10.10;
14 std::cout<<Add(x,y)<<std::endl;//相当于调用函数int Add(int,double)
15 std::cout<<Add(y,x)<<std::endl;//相当于调用函数double Add(double,int)
16
17 return0;
18 }
复制代码

结果:

在定义函数模板时要注意的一点是在template语句和函数模板定义语句之间是不允许插入其他的语句的。和一般函数一样,函数模板也可以重载:

View Code

结果:

函数模板与同名非模板函数也可以重载。比如:

View Code
复制代码
 1 #include "stdafx.h"
2 #include <iostream>
3
4
5 template <typename T>//加法函数模板
6 T Add(T x,T y)
7 {
8 std::cout<<"调用模板函数:";
9 return x+y;
10 }
11
12 int Add(int x,int y)
13 {
14 std::cout<<"调用非模板函数:";
15 return x+y;
16 }
17
18
19 int main()
20 {
21 int x=10,y=10;
22 std::cout<<Add(x,y)<<std::endl;//调用非模板函数
23
24 double x1=10.10,y1=10.10;
25 std::cout<<Add(x1,y1)<<std::endl;//调用模板函数
26
27 return0;
28 }
复制代码

结果:

就如示例代码运行的结果表明的一样,当模板函数和同名的非模板函数重载时,首先寻找与参数类型完全匹配的非模板函数,找到了,则调用它,如果没找到,则寻找函数模板,找到后具体化函数模板,而后调用该模板函数

  2.和函数模板一样,类模板就是建立一个通用类,其数据成员的类型、成员函数的返回类型和参数类型都不具体指定,用一个虚拟类型来代表。当使用类模板建立对象时,系统会根据实参的类型来取代类模板中的虚拟类型从而实现不同类的功能。其定义格式为:

  template <typename 类型参数>

  class 类名

  {

    类成员声明

  }

  或

  template <class 类型参数>

  class 类名

  {

    类成员声明

  }

在类成员声明里,成员数据类型、成员函数的返回类型和参数类型前面需加上类型参数。在类模板中成员函数既可以定义在类模板内,也可以定义在类模板外,在定义类模板外时C++有这样的规定:需要在成员函数定义之前进行模板声明,且在成员函数名之前加上“类名<类型参数>::”

  template <typename(class) 类型参数>

返回类型 类名<类型参数>::函数名(形参)

{

  函数体

}

而类模板定义对象的形式:

  类模板名<实际类型> 对象名;

  类模板名<实际类型> 对象名(实参);

示例说明如下:

View Code
复制代码
 1 #include "stdafx.h"
2 #include <iostream>
3 #include <string>
4
5 template <typename T>//在类模板定义之前,都需要加上模板声明
6 class BinaryOperation//二目运算类
7 {
8 private:
9 T x;
10 T y;
11 char op;
12 void add()
13 {
14 std::cout<<x<<op<<y<<"="<<x+y<<std::endl;
15 }
16 void sub()
17 {
18 std::cout<<x<<op<<y<<"="<<x-y<<std::endl;
19 }
20 void mul();
21 void div();
22 public:
23 BinaryOperation(T x,T y):x(x),y(y)
24 {
25 }
26 void determineOp(char op);
27 };
28
29
30 //在类外定义成员函数:
31 //在成员函数定义之前进行模板声明,
32 //且在成员函数名之前加上"类名<类型参数>::"
33 template <typename T>
34 void BinaryOperation <typename T>::mul()
35 {
36 std::cout<<x<<op<<y<<"="<<x*y<<std::endl;
37 }
38
39 template <typename T>
40 void BinaryOperation <typename T>::div()
41 {
42
43 std::cout<<x<<op<<y<<"="<<x/y<<std::endl;
44 }
45
46 template <typename T>
47 void BinaryOperation <typename T>::determineOp(char op)
48 {
49 this->op=op;
50 switch(op)
51 {
52 case'+':
53 add();
54 break;
55 case'-':
56 sub();
57 break;
58 case'*':
59 mul();
60 break;
61 case'/':
62 div();
63 break;
64 default:
65 break;
66 }
67 }
68
69 int main()
70 {
71
72 BinaryOperation<int> op(10,10);
73 op.determineOp('+');
74 op.determineOp('-');
75 op.determineOp('*');
76 op.determineOp('/');
77
78 return0;
79 }
复制代码

结果:

和函数模板一样,类模板也允许定义多个类型参数,这里不再一一举例了,有兴趣的朋友可以参考上述的示例代码尝试一下。

转载于:http://www.cnblogs.com/CaiNiaoZJ/archive/2011/08/15/2138705.html


http://www.cnblogs.com/gaojun/archive/2010/09/10/1823354.html



C++ 虚函数 http://blog.csdn.net/haoel/article/details/1948051/ 简而言之,C++使用虚函数来实现‘多态’,即使用父类指针指向子类实例,类似于Java中Abstract和Interface来实现多态。

C++ external 和static 修饰符 解析 http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html


未搞清楚的地方:

Java中的equals, JVM, Java NIO

原文:http://blog.csdn.net/haoel/article/details/6338025

操作。我们的面试官分不清楚什么是操作技能,什么是知识,他们甚至认为操作技能就是知识甚至经验。比如他们会 问如下的问题,请问Java中的 final是什么意思?怎么查看进程的CPU利用率?怎么编写一个管道程序?怎么查看进程的程序路径?VI中的拷贝粘贴命令是什么?包括面向对象的XX模 式是什么。等等。我以为,这些能够通过查况相关操作手册或是能够google到的东西只能说明这个人的操作技术,并不能说明他有知识或有经验

关于怎么查看的进程的程序路径:http://blog.csdn.net/eijnew/article/details/6185872 通过ps命令和进入/proc目录查找

http://hi.baidu.com/_kouu/item/7111e61acd04a9f487ad4ed0 关于linux的进程状态解析

设计模式,忘了,忘了,忘了

知识。知识是一个人认知和学习的体现,可能会是一些基础概念和知识。比如这些问题:TCP和UDP的优缺点比 较,链表和哈希表的优缺点的比较。什么是堆什么是栈?进程间是怎么通信的?进程和线程的优缺点?同步和异步的优缺点?面向对象的XX设计模式的主要原则是 什么,等等。我以为,“知其然”只是操作技术,“知其所以然”才是真正的知识。知识不够并不代表他不能工作,会操作技能就可以应付工作,但是知识的欠缺一定会限制你的经验和能力,同样会影响你的开发质量。

经验。经验通常跟一个人的经历有关系。一个人的知识范围,一个人经历过的事,通常会成为一个人经验的体现。面 试中,我们会问这些问题:你解决过最难的问题是什么?你是怎么设计这个系统的?你是怎么调试和测试你的程序的?你是怎么做性能调优的?什么样的代码是好的 代码?等等。对于工作年限不长的人来说,经历和做过的事的确会成为其经验的主要因素,尤其是业务上的有行业背景的东西。但是,我更以为,经验可能更多的是你对知识的运用和驾驭,是你对做过事情的反思和总结,是你对他人的学习,观察和交流









http://blog.csdn.net/haoel/article/details/4737425 :程序员小抄,很好的东东

拿出来一个:http://cs.fit.edu/~mmahoney/cse2050/how2cpp.html :How to program in C++


C++ Containers Cheat Sheet

Key

X   = container class   a, b   = objects of class X
T   = class which is stored in X   t   = object of class T
n   = number   i, j   = iterators of any type  
p, q, hint  = iterators of type X  key  = object of key class for X
comp  = comparator object  pred  = predicate object
bin_pred  = binary predicate object  = container object being adapted

Containers

template<class T, class A=allocator<T> > class vector
template<class T, class A=allocator<T> > class list
template<class T, class A=allocator<T> > class deque
template<class T, class Compare=less<T>, class A=allocator<T> > class set
template<class T, class Compare=less<T>, class A=allocator<T> > class multiset
template<class Key, class Mapped, class Compare=less<Key>, class A=allocator<Mapped> > class map
template<class Key, class Mapped, class Compare=less<Key>, class A=allocator<Mapped> > class multimap
template<class T, class Traits=char_traits<T>, class A=allocator<T> > class basic_string
template<class T, class Hash=hash<T>, class Eq=equal_to<T>, class A=allocator<T> > class hash_set
template<class T, class Hash=hash<T>, class Eq=equal_to<T>, class A=allocator<T> > class hash_multiset
template<class Key, class Mapped, class Hash=hash<Key>, class Eq=equal_to<Key>, class A=allocator<Mapped> > class hash_map
template<class Key, class Mapped, class Hash=hash<Key>, class Eq=equal_to<Key>, class A=allocator<Mapped> > class hash_multimap
template<class T, class Container=deque<T> > class stack
template<class T, class Container=deque<T> > class queue
template<class T, class Container=vector<T>, class Compare=less<class Container::value_type> > class priority_queue

Expressions grouped by container requirements,      * = non-standard container

Container

Expression Return type vector list     deque basic string set     multi  set map   multi  map hash  set* hash  multi set* hash  map* hash  multi map* stack queue priority queue
X::value_type T O O O O O O O O O O O O O O O
X::reference lvaue of T O O O O O O O O O O O O      
X::const_reference const lvalue of T O O O O O O O O O O O O      
X::iterator iterator to T O O O O O O O O O O O O      
X::const_iterator iterator to const T O O O O O O O O O O O O      
X::difference_type signed integral type O O O O O O O O O O O O      
X::size_type unsigned integral type O O O O O O O O O O O O O O O
X a   O O O O O O O O O O O O O O O
X a(b)   O O O O O O O O O O O O O O O
a.~X()   O O O O O O O O O O O O O O O
a = b X& O O O O O O O O O O O O O O O
swap(a, b) void O O O O O O O O O O O O      
a == b convertible to bool O O O O O O O O O O O O O O O
a < b convertible to bool O O O O O O O O O O O O O O O
a.begin() iterator orconst_iterator O O O O O O O O O O O O      
a.end() iterator orconst_iterator O O O O O O O O O O O O      
a.size() size_type O O O O O O O O O O O O O O O
a.max_size() size_type O O O O O O O O O O O O      
a.empty() convertible to bool O O O O O O O O O O O O O O O
a.swap(b) void O O O O O O O O O O O O      

Reversable Container

Expression Return type vector list     deque basic string set     multi  set map   multi  map hash  set* hash  multi set* hash  map* hash  multi map* stack queue priority queue
X::reverse_iterator iterator to T O O O O O O O O O O O O      
X::const_reverse_iterator iterator to const T O O O O O O O O O O O O      
a.rbegin() reverse_iterator orconst_reverse_iterator O O O O O O O O O O O O      
a.rend() reverse_iterator orconst_reverse_iterator O O O O O O O O O O O O      

Sequence

Expression Return type vector list     deque basic string set     multi  set map   multi  map hash  set* hash  multi set* hash  map* hash  multi map* stack queue priority queue
X a(n, t)   O O O O                      
X a(i, j)   O O O O O O O O O O O O      
a.insert(p, t) iterator O O O O                      
a.insert(p, n, t) void O O O O                      
a.insert(p, i, j) void O O O O                      
a.erase(q) iterator O O O O                      
a.erase(p, q) iterator O O O O                      
a.clear() void O O O O O O O O O O O O      
a.back() reference orconst_reference O O O                        
a.push_back(t) void O O O                        
a.pop_back() void O O O                        
a.front() reference orconst_reference O O O                        
a.push_front(t) void   O O                        
a.pop_front() void   O O                        
a[n] reference orconst_reference O   O O                      
a.at(n) reference orconst_reference O   O O                      

Associative Container

Expression Return type vector list     deque basic string set     multi  set map   multi  map hash  set* hash  multi set* hash  map* hash  multi map* stack queue priority queue
X::key_type Key         O O O O O O O O      
X::key_compare Compare         O O O O              
X::value_compare           O O O O              
X a(comp)           O O O O              
X a   O O O O O O O O O O O O O O O
X a(i, j, comp)           O O O O             O
X a(i, j)           O O O O O O O O     O
a.key_comp() key_compare         O O O O              
a.value_comp() value_compare         O O O O              
a.insert(t) pair<iterator, bool>         O   O   O   O        
iterator           O   O   O   O      
a.insert(hint, t) iterator         O O O O              
a.insert(i, j) void         O O O O O O O O      
a.erase(key) size_type         O O O O O O O O      
a.erase(q) void         O O O O O O O O      
a.erase(p, q) void         O O O O O O O O      
a.clear() void O O O O O O O O O O O O      
a.find(key) iterator or const_iterator         O O O O O O O O      
a.count(key) size_type         O O O O O O O O      
a.lower_bound(k) iterator or const_iterator         O O O O              
a.upper_bound(k) iterator or const_iterator         O O O O              
a.equal_range(k) pair<iterator,
     iterator> orpair<const_iterator,
     const_iterator>
        O O O O              

Container Specific

Expression Return type vector list     deque basic string set     multi  set map   multi  map hash  set* hash  multi set* hash  map* hash  multi map* stack queue priority queue
a.get_allocator() allocator_type O O O O O O O O O O O O      
a.assign(p, q) void O O O O                      
a.resize(n) void O O O O                      
a.resize(n, t) void O O O O                      
a.assign(n, t) void O O O O                      
a.capacity() size_type O                            
a.reserve(n) void O                            
a.splice(p, b) void   O                          
a.splice(p, b, i) void   O                          
a.splice(p, b, i,j) void   O                          
a.remove(t) void   O                          
a.remove_if(pred) void   O                          
a.unique() void   O                          
a.unique(bin_pred) void   O                          
a.merge(b) void   O                          
a.merge(b, comp) void   O                          
a.reverse() void   O                          
a.sort(comp) void   O                          
X::mapped_type Mapped (T.second)             O O     O O      
a[key] mapped_type             O       O        
X::container_type Container                         O O O
X a(c)                           O O O
X a(comp, c)                               O
X a(i, j, comp, c)                               O
a.push(t) void                         O O O
a.pop() void                         O O O
a.top() T& or const T&                           O O
a.front() T& or const T&                         O    
a.back() T& or const T&                         O    

Choosing a Container


http://www.linuxsoftware.co.nz/cppcontainers.html

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值