Debug : 在单独运行时,往往需要编译器提供一些库文件
Release : 可以在没有安装visual c++的computer上正常运行
常规设置
1)
在共享DLL中使用MFC : 表示把程序中用到的MFC类库作为动态链接库,这样编译生成器的程序比较小,但是在运行的时候,需要操作系统提供额外的动态库支持。
2)
在静态库中使用MFC : 表示把用到的MFC类的内容作为静态库加到程序中,这样编译产生的程序可以在任何Windwos环境下运行,但是程序的体积比较大。
3)
使用标准Windows库 : 表示不适用MFC类库,仅使用标准的Windows类库。
#define and const
宏的使用是在预处理的时候进行五条件的替换,并没有明确指定这个常量的数据类型、所以带来便利的同时也容易带来问题。
所以出现了const
枚举的使用---------------------------------
- enum Weekday
- {
- mon,
- tue,
- wed,
- thu,
- fri,
- sat,
- sun
- };
enum Weekday
{
mon,
tue,
wed,
thu,
fri,
sat,
sun
};
枚举默认的值是0,如果不想用默认,可以直接赋值
枚举定义之后,不能再修改其中某个元素的值
使用位操作符---------------------------------------------------
- cout << "use transpose operator :" << endl;
- int iValue = 1;
-
- iValue = iValue << 34;
- cout << "iValue value is : " << iValue << endl;
cout << "use transpose operator :" << endl;
int iValue = 1;
// iValue = iValue * 4;
iValue = iValue << 34; // 34 % 32 = 2左移 因为超过了int的大小空间
cout << "iValue value is : " << iValue << endl;
内联函数 :
可以更形象地称为内嵌函数,它是C++对函数的一种特殊修饰。当编译器编译程序时,如果发现某段代码在调用一个内联函数,它就不再去调用该函数,而是将该函数的代码整段插入当前函数调用的位置。这样就省去了函数调用的过程,提高了代码的执行效率。关键字inline
函数重载 :
1)函数重载的意义在于可以根据输入参数的类型或者个数,自动地在多个重载函数中查找与之匹配的重载函数,从而只能地决定采用哪个函数版本。
2)只有相互之间的参数类型或者个数不同,才可以构成合法的重载函数
函数的声明----也称为函数的接口
1)试一试在纯c中使用接口------------------------------------------------
2)尽量在函数中使用断言assert判断函数的有效性
3)函数的功能要做到单一----如果一个函数需要完成多项任务,最好拆分成多个函数
面向对象的知识 :
1)封装
在传统的结构化程序设计思想中,数据和算法是相互分离的。
在面向对象的程序设计思想中,对象就是封装数据和操作这些数据的算法的逻辑实体,也是现实世界中物体在程序中的反映,使用封装有的时候可以很好的保护对象的私有部分
2)继承
从父亲那里得到技能,自己又可以继续学习。比如我现在就站在前人的基础上学习的c++
3)多态
就是指对象在不同情况下具有不同形式的能力。多态机制使具有不同内部结构的对象可以共享相同的外部接口。比如,给别人一幅画,不一定是你自己画的,也可以直接把你老爸的画送出
想想 : 如何在面向对象程序设计思想上,考虑扩展、复用、可维护问题
new :
在new不成功是,不必去判断指针是否为null,因为new不成功时,系统会自动抛出std::bad_alloc异常,new操作永远不会返回null
拷贝构造函数 :
默认也会有拷贝构造函数,当类中含有指针类型的属性时,以拷贝内存形式出现的默认拷贝构造函数只能复制指针属性的值,而不能复制指针属性所指向的内存,在这个情况下需要自定义类的拷贝函数,完成指针属性等需要页数处理的属性的拷贝工作。
p163 拷贝构造函数
- namespace Zeng
- {
- class CTest_A
- {
- public:
- CTest_A( int iValue, char* cName )
- {
- this->m_iValue = iValue;
- this->m_pName = new char[ strlen( cName ) + 1 ];
- strcpy( m_pName, cName );
- }
-
- CTest_A( const CTest_A& rCG )
- {
- this->m_iValue = rCG.m_iValue;
- this->m_pName = new char[ strlen( rCG.m_pName ) + 1 ];
- strcpy( m_pName, rCG.m_pName );
- }
- void print()
- {
- cout << "CTest_G m_iValue value is : " << this->m_iValue << endl;
- cout << "CTest_G m_pName value is : " << this->m_pName << endl;
- cout << "CTest_G m_pName address is : " << *this->m_pName << endl;
- }
- public:
- int m_iValue;
- char* m_pName;
- };
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- Zeng::CTest_A CA( 10, "Zengraoli" );
- Zeng::CTest_A CA2( 10, "Zengraoli" );
- Zeng::CTest_A CA3( CG );
- cout << "CA print" << endl;
- CA.print();
-
- cout << "\n";
- cout << "CA2 print" << endl;
- CA2.print();
-
- cout << "\n";
- cout << "CA3 print" << endl;
- CA3.print();
- cout << "class CTest_A size is : " << sizeof( Zeng::CTest_A ) << endl;
-
- return 0;
- }
namespace Zeng
{
class CTest_A
{
public:
CTest_A( int iValue, char* cName )
{
this->m_iValue = iValue;
this->m_pName = new char[ strlen( cName ) + 1 ];
strcpy( m_pName, cName );
}
// 拷贝构造函数
CTest_A( const CTest_A& rCG )
{
this->m_iValue = rCG.m_iValue;
this->m_pName = new char[ strlen( rCG.m_pName ) + 1 ];
strcpy( m_pName, rCG.m_pName );
}
void print()
{
cout << "CTest_G m_iValue value is : " << this->m_iValue << endl;
cout << "CTest_G m_pName value is : " << this->m_pName << endl;
cout << "CTest_G m_pName address is : " << *this->m_pName << endl;
}
public:
int m_iValue;
char* m_pName;
}; // 试试拷贝构造函数
}
int _tmain(int argc, _TCHAR* argv[])
{
Zeng::CTest_A CA( 10, "Zengraoli" );
Zeng::CTest_A CA2( 10, "Zengraoli" );
Zeng::CTest_A CA3( CG );
cout << "CA print" << endl;
CA.print();
cout << "\n";
cout << "CA2 print" << endl;
CA2.print();
cout << "\n";
cout << "CA3 print" << endl;
CA3.print();
cout << "class CTest_A size is : " << sizeof( Zeng::CTest_A ) << endl;
return 0;
}
P166 操作符重载
函数重载和操作符重载-------------------------------------
#include "stdafx.h"
#include "iostream"
using namespace std;
namespace Zeng
{
class CTest_A
{
public:
CTest_A()
{
}
void print()
{
cout << "this is CTest_A print()" << endl;
}
}; // 占1个字节的大小
class CTest_B : virtual CTest_A
{
public:
CTest_B( int iValue ) : m_iValue( iValue )
{
}
void print()
{
cout << "m_iValue value is : " << m_iValue << endl;
}
private:
int m_iValue;
}; // 占8个字节的大小
class CTest_C : virtual CTest_A
{
public:
CTest_C()
{
}
}; // 占4个字节的大小
class CTest_D : virtual CTest_B
{
public:
CTest_D( int iValue ) : CTest_B( iValue )
{
this->m_iValue = iValue + 89;
}
void print()
{
cout << "m_iValue value is : " << this->m_iValue << endl;
}
private:
int m_iValue;
}; // 占16个字节的大小
class CTest_E : public CTest_A
{
public:
CTest_E( int iValue )
{
this->m_iValue = iValue + 89;
}
void print()
{
cout << "this is CTest_E not parameter's print()" << endl;
}
void print( int iValue )
{
cout << "this is CTest_E has parameter's print()" << endl;
}
/*
int print( int iValue )
{
cout << "this is CTest_E has parameter's print()" << endl;
return 0;
} // c++可以忽略函数的返回值,所以只能靠参数不同来进行函数重载
*/
private:
int m_iValue;
}; // 试试函数重载
class CTest_F
{
public:
CTest_F( int iValue )
{
this->m_iValue = iValue;
}
void print()
{
cout << "CTest_F m_iValue value is : " << this->m_iValue << endl;
}
const CTest_F& operator+ ( const CTest_F& rCF )
{
this->m_iValue += rCF.m_iValue;
return *this;
}
const CTest_F& operator= ( const CTest_F& rCF )
{
this->m_iValue = rCF.m_iValue;
return *this;
}
public:
int m_iValue;
}; // 试试操作符重载
}
int _tmain(int argc, _TCHAR* argv[])
{
Zeng::CTest_A CA;
CA.print();
cout << "class CTest_A size is : " << sizeof( Zeng::CTest_A ) << endl;
cout << "class CTest_B size is : " << sizeof( Zeng::CTest_B ) << endl;
cout << "class CTest_C size is : " << sizeof( Zeng::CTest_C ) << endl;
cout << "\n";
Zeng::CTest_D CD( 10 );
CD.print();
cout << "class CTest_D size is : " << sizeof( Zeng::CTest_D ) << endl;
cout << "\n";
Zeng::CTest_E CE( 10 );
CE.print();
CE.print(1);
cout << "class CTest_E size is : " << sizeof( Zeng::CTest_E ) << endl;
cout << "\n";
Zeng::CTest_F CF( 10 );
Zeng::CTest_F CF2( 89 );
CF = CF + CF2;
cout << "in class CTest_F override add after : " << sizeof( Zeng::CTest_F ) << endl;
CF.print();
CF = CF2;
cout << "in class CTest_F override equal after : " << sizeof( Zeng::CTest_F ) << endl;
CF.print();
cout << "class CTest_F size is : " << sizeof( Zeng::CTest_F ) << endl;
return 0;
}
构造函数私有化的含义---------------------------------------------
- namespace Rao
- {
- class CTest
- {
- public:
- static CTest* makeAnObject()
- {
-
- static CTest instance;
- return &instance;
- }
- ~CTest()
- {
- cout << "CTest Destructor...." << endl;
- }
- static int m_nValue;
- private:
- CTest()
- {
- m_nValue++;
- cout << "CTest Constructor...." << endl;
- }
-
- CTest( const CTest& CopyCTest )
- {
- m_nValue++;
- cout << "CopyCTest Constructor...." << endl;
- }
-
- const CTest& operator= ( const CTest& );
- };
- }
- main:
- int Rao::CTest::m_nValue;
-
- cout << "\n";
- cout << "use Constructor privatization :" << endl;
- Rao::CTest* RaoCTest = Rao::CTest::makeAnObject();
- cout << "m_nValue :" << Rao::CTest::m_nValue << endl;
- Rao::CTest* RaoCTest2 = Rao::CTest::makeAnObject();
- cout << "m_nValue :" << Rao::CTest::m_nValue << endl;
-
-
- Rao::CTest sg = *Rao::CTest::makeAnObject();
- cout << "m_nValue :" << Rao::CTest::m_nValue << endl;
namespace Rao
{
class CTest
{
public:
static CTest* makeAnObject()
{
// 程序结束的时候 自动释放
static CTest instance;
return &instance;
}
~CTest()
{
cout << "CTest Destructor...." << endl;
}
static int m_nValue;
private:
CTest()
{
m_nValue++;
cout << "CTest Constructor...." << endl;
}
CTest( const CTest& CopyCTest )
{
m_nValue++;
cout << "CopyCTest Constructor...." << endl;
}
const CTest& operator= ( const CTest& );
};
}
main:
int Rao::CTest::m_nValue;
cout << "\n";
cout << "use Constructor privatization :" << endl;
Rao::CTest* RaoCTest = Rao::CTest::makeAnObject();
cout << "m_nValue :" << Rao::CTest::m_nValue << endl;
Rao::CTest* RaoCTest2 = Rao::CTest::makeAnObject();
cout << "m_nValue :" << Rao::CTest::m_nValue << endl;
// 调用拷贝构造函数
Rao::CTest sg = *Rao::CTest::makeAnObject();
cout << "m_nValue :" << Rao::CTest::m_nValue << endl;
类的成员访问控制
public : 公有访问接口
protected : 1)可以供类自身访问的成员 2)可以供下级子类访问的成员
private : 仅供类自身访问的成员
友元函数
简单理解为 : 由于类成员的访问控制机制,很好地实现了数据的隐藏与封装,类的成员变量一般定义为私有成员,成员函数一般定义为公有成员,以此来提供类与外界间的通信接口;但有特殊的情况,比如需要定义某个函数/某个类,这个函数/类不是类CA的一部分,但又需要频繁地访问类CA的隐藏信息,所以C++提供了一个"friend"关键字来完成这个任务。
友元函数和友元类都需要试一试--------------------------------------P172
但需要记住的一点 :
1)友元关系不能被继承。这一点很好理解,我们跟某个类是朋友,并不表示我们跟这个类的儿子(派生类)同样是朋友。
2)友元关系是单向的,不具有交换性。
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
-
- namespace Zeng
- {
- class CTest_A
- {
- public:
- CTest_A( int iValue )
- {
- this->m_iValue = iValue;
- }
- void print()
- {
- cout << "CTest_A's m_iValue current value is : " << this->m_iValue << endl;
- }
- friend void firendFunction( const CTest_A& CA );
- friend class CTest_B;
- private:
- int m_iValue;
- };
-
- class CTest_B
- {
- public:
- CTest_B()
- {
- }
- void print( const CTest_A& CA )
- {
- cout << "this's firend class CTest_B print : " << CA.m_iValue << endl;
- }
- private:
- };
-
- void firendFunction( const CTest_A& CA )
- {
- cout << "this's firend function print : " << CA.m_iValue << endl;
- }
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- Zeng::CTest_A CA( 100 );
- firendFunction( CA );
-
- cout << "\n";
- Zeng::CTest_B CB;
- CB.print( CA );
-
- return 0;
- }
抽象一般分为属性抽象和行为抽象两种。前者寻找一类对象共有的属性或者状态变量,后者则寻找这类对象所具有的共同行为特征。在分析新的对象时,应该从属性和行为两个方面进行抽象和概括,提取对象的共有也行。有了抽象,那么就可以提取出来当做接口(虚函数),可以直接变成类的成员属性和成员函数。
如何在子类中调用从父类继承并且已经被重写的函数?--------------------
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
-
- namespace Zeng
- {
- class CTest_A
- {
- public:
- CTest_A( int iValue )
- {
- this->m_iValue = iValue;
- }
- void print()
- {
- cout << "CTest_A's m_iValue current value is : " << this->m_iValue << endl;
- }
- private:
- int m_iValue;
- };
-
- class CTest_B : public CTest_A
- {
- public:
- CTest_B( int iValue ) : CTest_A( iValue )
- {
- this->m_iValue = iValue;
- }
- void print()
- {
- cout << "CTest_B's m_iValue current value is : " << this->m_iValue << endl;
- }
- private:
- int m_iValue;
- };
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- Zeng::CTest_A* CB2 = new Zeng::CTest_B( 8 );
- CB2->print();
-
- cout << "class CTest_A size is : " << sizeof( Zeng::CTest_A ) << endl;
- cout << "class CTest_B size is : " << sizeof( Zeng::CTest_B ) << endl;
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
namespace Zeng
{
class CTest_A
{
public:
CTest_A( int iValue )
{
this->m_iValue = iValue;
}
void print()
{
cout << "CTest_A's m_iValue current value is : " << this->m_iValue << endl;
}
private:
int m_iValue;
};
class CTest_B : public CTest_A
{
public:
CTest_B( int iValue ) : CTest_A( iValue )
{
this->m_iValue = iValue;
}
void print()
{
cout << "CTest_B's m_iValue current value is : " << this->m_iValue << endl;
}
private:
int m_iValue;
}; // virtual CTest_A比普通的public CTest_A多了一个指向父类的指针
}
int _tmain(int argc, _TCHAR* argv[])
{
Zeng::CTest_A* CB2 = new Zeng::CTest_B( 8 ); // 构造函数的执行顺序是先父类在子类
CB2->print(); // 此时调用的是父类的print函数,因为指针时指向CTest_A的,如果在CTest_B的print前面加virtual还调用CTest_B的
cout << "class CTest_A size is : " << sizeof( Zeng::CTest_A ) << endl;
cout << "class CTest_B size is : " << sizeof( Zeng::CTest_B ) << endl;
return 0;
}
this指针 :
比如在类中
- class Base
- {
- public:
- void SetValue( int nVal )
- {
- m_nVal = nVal;
- }
- private:
- int m_nVal;
- }
class Base
{
public:
void SetValue( int nVal )
{
m_nVal = nVal;
}
private:
int m_nVal;
}
SetValue函数中并没有指明m_nVal成员变量到底属于哪一个对象类似的问题...其实编译器隐藏掉了,应该是this->m_nVal = nVal;当然在使用的时候,可以直接在这个变量前面显示的加上去。
但是,this指针在实际开发中的意义却是,用来返回指向对象本身的指针,以实现对象链式引用,或者避免对同一对象进行赋值操作。例如
- class Point
- {
- public:
- Point( int x, int y ) : m_nX( x ), m_nY( y )
- {};
- void operator = (Point& pt)
- {
-
- if( &pt == this )
- {
- m_nX = pt.m_nX;
- m_nY = pt.m_nY;
- }
- }
-
- Point& Move( int x, int y )
- {
- m_nX += x;
- m_nY += y;
-
- return *this;
- }
- private:
- int m_nX;
- int m_nY;
- };
-
- Point pt1(2, 4);
- Point pt2(0, 0);
-
- pt1 = pt1;
-
- pt1.Move( 1, 1 ).Move( 2, 4 );
class Point
{
public:
Point( int x, int y ) : m_nX( x ), m_nY( y )
{};
void operator = (Point& pt)
{
// 判断传递进来而定参数是否是这个对象本身,是,则不进行赋值操作
if( &pt == this )
{
m_nX = pt.m_nX;
m_nY = pt.m_nY;
}
}
// 移动点的位置
Point& Move( int x, int y )
{
m_nX += x;
m_nY += y;
// 返回对象本身,这样可以利用函数返回值进行链式引用
return *this;
}
private:
int m_nX;
int m_nY;
};
Point pt1(2, 4);
Point pt2(0, 0);
// 自己给自己赋值 试试
pt1 = pt1;
// 移动一下,再移动一下 看看什么是返回对象的链式引用------------------------
pt1.Move( 1, 1 ).Move( 2, 4 );
指针* :
1)指针加1或者减1,会使指针指向的地址增加或者减少一个对象的数据类型的长度。
2)指针类型的转换
虽然指针类型的转换可能会带来不可预料的麻烦,就行goto语句一样,比如
- int* pInt;
- float* pFloat = ( float* )pInt;
int* pInt;
float* pFloat = ( float* )pInt;
这种方法比较直接,但是非常粗鲁,因为他允许你在任何类型之间进行转换,另外这种类型的转换方式在程序语句中很难识别,代码阅读者可能会忽略类型转换的语句。
为了克服这些缺点,C++引入了新的类型转换操作符static_cast来代替上面的类型转换
static_cast<类型说明符>(表达式)
static_cast
指针的类型转换-------------------------------------------------------
#include "stdafx.h"
#include "iostream"
using namespace std;
namespace Zeng
{
class CTest_A
{
public:
CTest_A()
{}
virtual void Print()
{
cout << "this's CTest_A's Print :" << endl;
}
};
class CTest_B : public CTest_A
{
public:
CTest_B()
{}
void Print()
{
cout << "this's CTest_B's Print :" << endl;
}
};
class CTest_C
{
public:
CTest_C()
{}
void Print()
{
cout << "this's CTest_C's Print :" << endl;
}
};
class CTest_D
{
public:
CTest_D() : m_iNum(14)
{
}
void ConstPrint() const
{
cout << "ConstPrint print CTest_D m_iNum current value is :" << m_iNum << endl;
}
void Print()
{
cout << "Print print CTest_D m_iNum current value is :" << m_iNum << endl;
}
int m_iNum;
}; // 用来测试const_cast转换操作符
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "CTest_B convert to CTest_A :" << endl;
Zeng::CTest_B* B = new Zeng::CTest_B();
Zeng::CTest_A* A = static_cast< Zeng::CTest_A* >( B );
A->Print();
cout << "\n";
cout << "CTest_A convert to CTest_B :" << endl;
Zeng::CTest_A* A2 = new Zeng::CTest_A();
Zeng::CTest_B* B2 = static_cast< Zeng::CTest_B* >( A2 );
B2->Print();
/*
cout << "\n";
cout << "CTest_B convert to CTest_C :" << endl;
Zeng::CTest_B* B3 = new Zeng::CTest_B();
Zeng::CTest_C* C = static_cast< Zeng::CTest_C* >( B3 );
// the CTest_B has nothing to do with CTest_C, so this convert been an error !
B2->Print();
*/
cout << "\n";
cout << "CTest_B convert to CTest_C :" << endl;
Zeng::CTest_B* B3 = new Zeng::CTest_B();
Zeng::CTest_C* C = reinterpret_cast< Zeng::CTest_C* >( B3 );
// reinterpret_cast should be convert CTest_B to CTest_C,
C->Print();
cout << "\n";
cout << "CTest_A dynamic_cast to CTest_B :" << endl;
Zeng::CTest_A* A4 = new Zeng::CTest_A();
Zeng::CTest_B* B4 = dynamic_cast< Zeng::CTest_B* >( A4 ); // dynamic_cast要求CTest_B必须要有虚函数
// B4->Print(); // 就算是有虚函数,dynamic_cast在处理向下转行的时候,得到的也是NULL
cout << "\n";
cout << "CTest_B dynamic_cast to CTest_A :" << endl;
Zeng::CTest_B* A5 = new Zeng::CTest_B();
Zeng::CTest_A* B5 = dynamic_cast< Zeng::CTest_A* >( A5 ); // dynamic_cast要求CTest_B必须要有虚函数
B5->Print(); // 就算是有虚函数,dynamic_cast在处理向上转行的时候,得到的是和static_cast一样的结果
int iNum = 14;
int* pINum = &iNum;
char* pCTest = "a";
/* pCTest = reinterpret_cast< int* >( pINum );*/
cout << "pINum point value is : " << *pINum << endl;
// reinterpret_cast可以在任意指针中转换,即使这两者之间没什么关系
pINum = reinterpret_cast< int* >( pCTest );
cout << "pINum point value is : " << *pINum << endl;
cout << "\n";
const int iNum2 = 14;
const int* piNum = &iNum2;
int* piValue = const_cast< int* >( piNum );
*piValue = 70;
cout << "use operator const_cast current *piValue value is : " << *piValue << endl;
cout << "use operator const_cast current *piNum value is : " << *piNum << endl;
cout << "use operator const_cast current iNum value is : " << iNum2 << endl;
cout << "\n";
const Zeng::CTest_D CD;
// CD.m_iNum = 70; // error C3892: “CD”: 不能给常量赋值
const Zeng::CTest_D* pCD = &CD;
Zeng::CTest_D* pCD2 = const_cast< Zeng::CTest_D * >( pCD );
pCD2->m_iNum = 70;
cout << "use const_cast operator as object :" << endl;
cout << "pCD2 is not's const point, this point m_iNum value is" << endl;
pCD2->Print();
cout << "CD is a class object, this object m_iNum value is" << endl;
CD.ConstPrint(); // const 对象只能访问class里面带有const的函数
cout << "pCD is a const point, this point m_iNum value is" << endl;
pCD->ConstPrint();
return 0;
}
二级指针的使用** :
一个例子既可以知道
- char* arrMouth[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
- char** pMouth = arrMouth;
- int nIndex;
- cout << "请输入月份对应的数字 : " << endl;
- cin >> nIndex;
-
-
- char* pCurMonth = *( pMouth + ( nIndex - 1 ) );
- cout << "对应的月份是 : " << pCurMonth << endl;
- cout << "对应的月份是 : " << *pCurMonth << endl;
char* arrMouth[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
char** pMouth = arrMouth;
int nIndex;
cout << "请输入月份对应的数字 : " << endl;
cin >> nIndex;
// 之所以是char*是因为每一个月份都是字符串类型的
char* pCurMonth = *( pMouth + ( nIndex - 1 ) );
cout << "对应的月份是 : " << pCurMonth << endl;
cout << "对应的月份是 : " << *pCurMonth << endl;
指针在函数中的作用 :
1)在函数的参数中使用指针,在传递大数据的时候可以有效减少函数调用的开销
- void SumArray( const int* pArray, int nArrayCount, int* nSum )
- {
- *nSum = 0;
-
-
- for (int i = 0; i < nArrayCount; i++)
- {
- *nSum += *pArray;
- pArray++;
- }
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- cout << "指针作为函数参数:" << endl;
- int nArraySum;
- int iArray[5] = { 1, 2, 3, 4, 5};
-
- SumArray( iArray, 5, &nArraySum );
- cout << "运算的和为:" << nArraySum << endl;
-
- return 0;
- }
void SumArray( const int* pArray, int nArrayCount, int* nSum )
{
*nSum = 0;
// 遍历整个数组
for (int i = 0; i < nArrayCount; i++)
{
*nSum += *pArray;
pArray++;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "指针作为函数参数:" << endl;
int nArraySum;
int iArray[5] = { 1, 2, 3, 4, 5};
SumArray( iArray, 5, &nArraySum );
cout << "运算的和为:" << nArraySum << endl;
return 0;
}
2)指针作为函数返回值
当函数的返回值是指针时,这个函数就是指针型函数。指针型函数通常用来获取一些指针变量的值。
在类中返回一个指针类型的成员变量,经常会使用到指针作为函数返回值
- char* GetName()
- {
- return m_pName;
- }
char* GetName()
{
return m_pName;
}
引用& :
1)引用的本质,就是变量的别名,通俗地讲,就是变量的绰号。对变量的引用进行任何操作,就是对变量本身的操作,就想不管是叫你小名还是叫你的绰号,都是在叫同一个人。
- cout << "use reference:" << endl;
- int nIntValue = 99999;
- int& rIntValue = nIntValue;
- cout << "rIntValue:" << rIntValue << endl;
- cout << "rIntValue memory address:" << &rIntValue << endl;
- cout << "nIntValue:" << nIntValue << endl;
- cout << "nIntValue memory address:" << &nIntValue << endl;
-
- rIntValue = 1;
- cout << "modify rIntValue after:" << rIntValue << endl;
- cout << "rIntValue memory address:" << &rIntValue << endl;
- cout << "current nIntValue:" << nIntValue << endl;
- cout << "nIntValue memory address:" << &nIntValue << endl;
-
- nIntValue = 8888;
- cout << "modify nIntValue after:" << nIntValue << endl;
- cout << "nIntValue memory address:" << &nIntValue << endl;
- cout << "current rIntValue:" << rIntValue << endl;
- cout << "rIntValue memory address:" << &rIntValue << endl;
cout << "use reference:" << endl;
int nIntValue = 99999;
int& rIntValue = nIntValue;
cout << "rIntValue:" << rIntValue << endl;
cout << "rIntValue memory address:" << &rIntValue << endl;
cout << "nIntValue:" << nIntValue << endl;
cout << "nIntValue memory address:" << &nIntValue << endl;
rIntValue = 1;
cout << "modify rIntValue after:" << rIntValue << endl;
cout << "rIntValue memory address:" << &rIntValue << endl;
cout << "current nIntValue:" << nIntValue << endl;
cout << "nIntValue memory address:" << &nIntValue << endl;
nIntValue = 8888;
cout << "modify nIntValue after:" << nIntValue << endl;
cout << "nIntValue memory address:" << &nIntValue << endl;
cout << "current rIntValue:" << rIntValue << endl;
cout << "rIntValue memory address:" << &rIntValue << endl;
2)在函数参数中使用,传递引用可以直接对这个参数进行修改
- void Increase( int& nVal )
- {
- nVal += 1;
- }
void Increase( int& nVal )
{
nVal += 1;
}
三种函数参数和返回值的方法 :
1)
传值 是指直接将实际参数的值复制给形参,完成参数的传递
形式简单自然,便于理解,代码可读性高
2)
传指针 是指将需要传递的数据的指针作为参数进行传递
效率高,可以同时传入传出参数
3)
传引用 将需要传递的数据的引用作为参数进行传递
效率高,可以同时传入传出参数,形式自然
异常处理
异常的使用,会降低程序的性能,但是,如果使用得当,有时也可以提高程序的性能。比如,如果函数的参数是指针,则需要在函数入口处对这个指针的有效性进行检查。
- double Divede( int a, int b )
- {
- if ( 0 == b )
- {
- throw "除数不能为 0 ";
- }
- return ( double )a / b;
- }
-
- cout << "use exception deal : " << endl;
- try
- {
- Divede( 2, 0 );
- cout << "throw a exception : " << endl;
- }
- catch ( char* pMsg )
- {
- cout << "catch a exception : " << pMsg << endl;
- }
- catch (...)
- {
- cout << "catch a exception : " << endl;
- }
-
- cout << "is this appcation exit ? : " << endl;
double Divede( int a, int b )
{
if ( 0 == b )
{
throw "除数不能为 0 ";
}
return ( double )a / b;
}
cout << "use exception deal : " << endl;
try
{
Divede( 2, 0 );
cout << "throw a exception : " << endl;
}
catch ( char* pMsg )
{
cout << "catch a exception : " << pMsg << endl;
}
catch (...)
{
cout << "catch a exception : " << endl;
}
cout << "is this appcation exit ? : " << endl;
名字空间namespace :
主要在多人同时开发时候使用,避免冲突
- namespace Zeng
- {
- class CTest
- {
- public:
- void Print()
- {
- cout << "this is namespace Zeng's Print" << endl;
- }
- };
- }
-
- cout << "use namespace Zeng ? : " << endl;
- Zeng::CTest CZengText;
- CZengText.Print();
namespace Zeng
{
class CTest
{
public:
void Print()
{
cout << "this is namespace Zeng's Print" << endl;
}
};
}
cout << "use namespace Zeng ? : " << endl;
Zeng::CTest CZengText;
CZengText.Print();
自定义类型的使用typedef :
后代前,以后使用byte就相当于使用了unsigned char
- typedef unsigned char byte;
typedef unsigned char byte;
宏的使用#define
1)简单的使用
#define MAXSIZE 100
2)宏直接分配数组
- #define myInitArray(ArrayName, ArraySize, InitValue) byte ArrayName[ArraySize + 1] = InitValue
#define myInitArray(ArrayName, ArraySize, InitValue) byte ArrayName[ArraySize + 1] = InitValue
3)宏中定义函数
- #ifndef SAFE_DELETE
- #define SAFE_DELETE( p ) { \
- if( NULL != p ) \
- { \
- delete p; p = NULL; \
- cout << "safe delete..." << endl; \
- } }
- #endif
-
- #ifndef SAFE_DELETE_ARRAY
- #define SAFE_DELETE_ARRAY( p ) { \
- if( NULL != p ) \
- { \
- delete[] p; p = NULL; \
- cout << "safe delete[]..." << endl; \
- } }
- #endif
-
-
- Zeng::CTest* CZengText2 = new Zeng::CTest;
- SAFE_DELETE( CZengText2 );
#ifndef SAFE_DELETE
#define SAFE_DELETE( p ) { \
if( NULL != p ) \
{ \
delete p; p = NULL; \
cout << "safe delete..." << endl; \
} }
#endif
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY( p ) { \
if( NULL != p ) \
{ \
delete[] p; p = NULL; \
cout << "safe delete[]..." << endl; \
} }
#endif
Zeng::CTest* CZengText2 = new Zeng::CTest;
SAFE_DELETE( CZengText2 );
用const保护数据
1)const定义常量
- const int number = 1;
- const int* pNumber;
- int const* pNumber;
- int* const pNumber = &number;
- const int* const pNumber = &number;
- const int& number = number;
const int number = 1; // 声明一个整形常量并复制为1
const int* pNumber; // 声明一个常量型指针,指针所指向的变量的值不能改变,也就是一个常量
int const* pNumber; // 声明一个常量整型指针,意义同上
int* const pNumber = &number; // 声明一个整型常量指针,指针不能修改
const int* const pNumber = &number;// 声明一个常量整型常量指针,指针和指针所指向的变量值都不能改变
const int& number = number; // 声明一个常量整型引用
2)根据const实在*的位置判断 :
const在*左边,则表示const修饰的是int,这个指针指向的int变量的值不能修改,而指针本身的值是可变的;
如果const在*的右边,则表示const修饰的是指针,这个指针的值不能在声明后修改,所以在声明这样的指针时必须赋初值,而这个指针所指向的int变量的值是可变的。
3)在函数参数中加入const
表示这只是一个传入参数,在整个函数内部不能被修改。
4)修饰类成员函数
在声明类的成员函数时,如果在末尾加上const修饰,则表示在这个成员函数内不得改变该对象的任何数据。这种模式常用来表示"对象数据制度"的访问模式。
- namespace Zeng
- {
- class CTest
- {
- public:
- void Print() const
- {
- m_nValue = 1;
- cout << "this is namespace Zeng's Print" << endl;
- }
- private:
- int m_nValue;
- };
- }
namespace Zeng
{
class CTest
{
public:
void Print() const
{
m_nValue = 1;
cout << "this is namespace Zeng's Print" << endl;
}
private:
int m_nValue;
};
}
// 提示error : error C2166: 左值指定 const 对象
STL:
算法(algorithm)+容器(container)+迭代器(iterator) = STL
容器(container)
主要含有deque(双端队列)、queue(队列)、stack(堆栈容器)、vector(动态数组容器)、map multimap unordered_map unorderd_multimap(映射容器 由{键, 值}对组成)、set multiset unordered_set
unordered_multiset(集合容器)、algorithm(通用算法, 包括比较、交换、查找、排序等)、functional(模板类)、string(字符串类)、regex(正则表达式)、memory(定义了跟内存操作相关的组件, 例如智能指针等)
vector相对于数组来说,他可以合理利用空间,让程序有更大的可扩展性
函数模板
1)当编译器发现一个函数模板的调用后,将根据实参的实际数据类型来确认是否匹配函数模板中对应的形参,然后生成一个重载函数。根据参数类型的不同,一个函数模板可以随时变成各种不同的重载
函数,从而实集类型的处理。
2)比如max函数---------------------能够比较int、float、string
temple<typename 标识符>
返回值类型 函数名(形参表)
{
//函数体
}
类模板
1)类模板的声明
temple<typename 标识符>
class 类名
{
//类的定义
}
2)定义一个用于比较两个数的类模板compare
- #include "stdafx.h"
- #include<vector>
- #include<string>
- #include<iostream>
- #include<algorithm>
- using namespace std;
-
- template <typename T>
- T compare( const T a, const T b)
- {
- return ( a > b ? a : b );
- }
- template <>
- string compare( const string a, const string b)
- {
- return ( a.size() > b.size() ? a : b );
- }
-
- int main()
- {
- const int ii = 10;
- const int ij = 20;
- cout << "return the max value is : " << compare<int>( ii, ij ) << endl;
-
- const float fi = 0.7f;
- const float fj = 1.2f;
- cout << "return the max value is : " << compare<float>( fi, fj ) << endl;
-
- const string strN = "aaaaaaaaaaa";
- const string strM = "zengraoli";
- cout << "return the max value is : " << compare<string>( strN, strM ) << endl;
-
- return 0;
- }
#include "stdafx.h"
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
template <typename T>
T compare( const T a, const T b)
{
return ( a > b ? a : b );
}
template <>
string compare( const string a, const string b)
{
return ( a.size() > b.size() ? a : b );
}
int main()
{
const int ii = 10;
const int ij = 20;
cout << "return the max value is : " << compare<int>( ii, ij ) << endl;
const float fi = 0.7f;
const float fj = 1.2f;
cout << "return the max value is : " << compare<float>( fi, fj ) << endl;
const string strN = "aaaaaaaaaaa";
const string strM = "zengraoli";
cout << "return the max value is : " << compare<string>( strN, strM ) << endl;
return 0;
}
模板的实例化
1)隐式实例化
常用方式,实例化为
compare<int> intcompare(2, 3)
2)显示实例化
在声明时,直接在template关键字后接函数的声明,且函数标识符后接模板参数
比如:
template int compare<int> intcompare( int, int );
用模板使用通用算法-------------------------------------------------------------------------
actioncontainer 有一个撤销和恢复的通用功能
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
-
- template<typename T>
- class CActionContainer
- {
- public:
- CActionContainer()
- : m_nRedoPos( 0 ), m_nUndoPos( 0 )
- {
- }
- void add( T value );
- T redo();
- T undo();
- private:
- int m_nRedoPos;
- int m_nUndoPos;
-
- const static int ActionContainerSize = 5;
-
- T m_RedoAction[ ActionContainerSize ];
- T m_UndoAction[ ActionContainerSize ];
- };
- template<typename T>
- void CActionContainer<T>::add( T value )
- {
-
- if ( m_nUndoPos > ActionContainerSize )
- {
- m_nUndoPos = m_nUndoPos - 1;
- for ( int i = 0; i < ActionContainerSize; i++ )
- {
- m_UndoAction[i] = m_UndoAction[ i + 1];
- }
- }
- m_UndoAction[ m_nUndoPos++ ] = value;
- }
-
-
- template <typename T>
- T CActionContainer<T>::undo()
- {
-
- m_RedoAction[ m_nRedoPos++ ] = m_UndoAction[ --m_nUndoPos ];
- return m_UndoAction[ m_nUndoPos ];
- }
-
-
- template <typename T>
- T CActionContainer<T>::redo()
- {
-
- m_UndoAction[ m_nUndoPos++ ] = m_RedoAction[ --m_nRedoPos ];
- return m_RedoAction[ m_nRedoPos ];
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- CActionContainer<int> intaction;
- intaction.add( 1 );
- intaction.add( 2 );
- intaction.add( 3 );
- intaction.add( 4 );
- intaction.add( 5 );
-
- int iUndo = intaction.undo();
- cout << "pass undo current value is : " << iUndo << endl;
- iUndo = intaction.undo();
- cout << "second pass undo current value is : " << iUndo << endl;
-
- int iRedo = intaction.redo();
- cout << "pass redo current value is : " << iRedo << endl;
- iRedo = intaction.redo();
- cout << "second pass redo current value is : " << iRedo << endl;
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
template<typename T>
class CActionContainer
{
public:
CActionContainer()
: m_nRedoPos( 0 ), m_nUndoPos( 0 )
{
}
void add( T value );
T redo();
T undo();
private:
int m_nRedoPos;
int m_nUndoPos;
// Container size
const static int ActionContainerSize = 5;
// record array
T m_RedoAction[ ActionContainerSize ];
T m_UndoAction[ ActionContainerSize ];
};
template<typename T>
void CActionContainer<T>::add( T value )
{
// if the container is full, adjust the pos of the container to add
if ( m_nUndoPos > ActionContainerSize )
{
m_nUndoPos = m_nUndoPos - 1;
for ( int i = 0; i < ActionContainerSize; i++ )
{
m_UndoAction[i] = m_UndoAction[ i + 1];
}
}
m_UndoAction[ m_nUndoPos++ ] = value;
}
// undo operator
template <typename T>
T CActionContainer<T>::undo()
{
// copy the revocation action to restore of the array
m_RedoAction[ m_nRedoPos++ ] = m_UndoAction[ --m_nUndoPos ];
return m_UndoAction[ m_nUndoPos ];
}
// redo operaor
template <typename T>
T CActionContainer<T>::redo()
{
// copy recovery action to the revocation of the array
m_UndoAction[ m_nUndoPos++ ] = m_RedoAction[ --m_nRedoPos ];
return m_RedoAction[ m_nRedoPos ];
}
int _tmain(int argc, _TCHAR* argv[])
{
CActionContainer<int> intaction;
intaction.add( 1 );
intaction.add( 2 );
intaction.add( 3 );
intaction.add( 4 );
intaction.add( 5 );
int iUndo = intaction.undo();
cout << "pass undo current value is : " << iUndo << endl;
iUndo = intaction.undo();
cout << "second pass undo current value is : " << iUndo << endl;
int iRedo = intaction.redo();
cout << "pass redo current value is : " << iRedo << endl;
iRedo = intaction.redo();
cout << "second pass redo current value is : " << iRedo << endl;
return 0;
}
泛型编程
1)
通过使用模板,可以使程序具有更好的代码重用性。泛型编程就是一种大量使用模板来实现更好的代码重用性的编程方式
2)
泛型编程的代表作品STL是一种高效、泛型、可交互操作的软件组件。其中算法是泛型的,不与任何特定的数据结构或对象类型联系在一起。
STL容器
1)
顺序容器
deque(双端队列)、list(线性表)、vector(动态数组容器)
基于这三种基本的顺序容器又可以构造出一些专门的容器,用于比较特殊的数据结构,包括heap(堆)、stack(栈)、queue(队列)、priority queue(优先队列)
2)
关联容器
所容纳的对象时有{键、值}对组成
3)
操作容器中的数据元素
接受用户输入并将数据保存到容器中
在开始位置插入一个数据
删除容器中的前三个数据
清空容器中的所有数据
- #include "stdafx.h"
- #include<vector>
- #include<string>
- #include<iostream>
- #include<algorithm>
- using namespace std;
-
- void vecDisplay( const float fValue )
- {
- cout << "current value is : " << fValue << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<float> vecScore;
- float fi = 0.0f;
- for ( int i = 0; i < 5; i++ )
- {
- cin >> fi;
- vecScore.push_back(fi);
- }
- cout << "input the value : " << endl;
- for_each( vecScore.begin(), vecScore.end(), vecDisplay );
-
- const float fj = 0.02f;
- vecScore.insert( vecScore.begin(), fj );
- cout << "\n";
- cout << "in the begin insert a number 0.02 : " << endl;
- for_each( vecScore.begin(), vecScore.end(), vecDisplay );
-
- vecScore.erase( vecScore.begin() );
- vecScore.erase( vecScore.begin() );
- vecScore.erase( vecScore.begin() );
- cout << "\n";
- cout << "delete vec in the before three number : " << endl;
- for_each( vecScore.begin(), vecScore.end(), vecDisplay );
-
- vecScore.clear();
- cout << "\n";
- cout << "clear vec : " << endl;
- for_each( vecScore.begin(), vecScore.end(), vecDisplay );
- return 0;
- }
#include "stdafx.h"
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
void vecDisplay( const float fValue )
{
cout << "current value is : " << fValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScore;
float fi = 0.0f;
for ( int i = 0; i < 5; i++ )
{
cin >> fi;
vecScore.push_back(fi);
}
cout << "input the value : " << endl;
for_each( vecScore.begin(), vecScore.end(), vecDisplay );
const float fj = 0.02f;
vecScore.insert( vecScore.begin(), fj );
cout << "\n";
cout << "in the begin insert a number 0.02 : " << endl;
for_each( vecScore.begin(), vecScore.end(), vecDisplay );
vecScore.erase( vecScore.begin() );
vecScore.erase( vecScore.begin() );
vecScore.erase( vecScore.begin() );
cout << "\n";
cout << "delete vec in the before three number : " << endl;
for_each( vecScore.begin(), vecScore.end(), vecDisplay );
vecScore.clear();
cout << "\n";
cout << "clear vec : " << endl;
for_each( vecScore.begin(), vecScore.end(), vecDisplay );
return 0;
}
STL迭代器
1)
容器和算法结合起来的黏合剂
和指针的区别,迭代器不一定具有地址值
2)
按照使用的目的不同,各个容器都提供了多种类型的迭代器。比如只读迭代器,前移迭代器等。跟指针类似迭代器前面加上*运算符能够获取这个迭代器所指向的数据;可以使用++或者--来将迭代器向
前或者向后移动一个位置,让它指向容器中的其他位置的数据元素。如果迭代器到达容器中的最后一个元素的后面,则迭代器编程past_the_end值,使用past_the_end值的迭代器来访问数据元素是非法
的,就好像使用NULL值的指针一样。
3)遍历容器
- #include "stdafx.h"
- #include<vector>
- #include<string>
- #include<iostream>
- #include<algorithm>
- using namespace std;
-
- int main()
- {
- vector<int> vecScore;
- vecScore.push_back( 50 );
- vecScore.push_back( 60 );
- vecScore.push_back( 70 );
- vecScore.push_back( 80 );
- vecScore.push_back( 90 );
-
- vector<int>::iterator it;
- for ( it = vecScore.begin(); it != vecScore.end(); it++ )
- {
- cout << "print current value : " << ( *it ) << endl;
- }
-
- return 0;
- }
#include "stdafx.h"
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
vector<int> vecScore;
vecScore.push_back( 50 );
vecScore.push_back( 60 );
vecScore.push_back( 70 );
vecScore.push_back( 80 );
vecScore.push_back( 90 );
vector<int>::iterator it;
for ( it = vecScore.begin(); it != vecScore.end(); it++ )
{
cout << "print current value : " << ( *it ) << endl;
}
return 0;
}
4)一般使用
a、对于对象,一般存放该对象的指针
b、小心清理容器中保存的对象指针,如果容器中保存的是对象,那么在容器析构的时候容器会自动清理这些对象。但是,如果存放对象指针,那么在容器析构的时候,首先要释放这些指针所指向的对象。
- #include "stdafx.h"
- #include "vector"
- #include "string"
- #include "algorithm"
- #include "iostream"
- using namespace std;
-
- class CStudent
- {
- public:
- CStudent( int iHeight ) : m_nHeight( iHeight )
- {
-
- }
- int GetHeight() const
- {
- return m_nHeight;
- }
- private:
- int m_nHeight;
- };
-
- void vecDisplay( CStudent* pSt )
- {
- cout << "current value is : " << pSt->GetHeight() << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<CStudent *> vecStudent;
- CStudent* CTest_A = new CStudent( 165 );
- CStudent* CTest_B = new CStudent( 175 );
- CStudent* CTest_C = new CStudent( 185 );
- vecStudent.push_back( CTest_A );
- vecStudent.push_back( CTest_B );
- vecStudent.push_back( CTest_C );
-
- cout << "Init vector : " << endl;
- for_each( vecStudent.begin(), vecStudent.end(), vecDisplay );
-
- vector<CStudent *>::iterator it;
- for ( it = vecStudent.begin(); it != vecStudent.end(); it++ )
- {
- if ( NULL != ( *it ))
- {
- delete ( *it );
- }
- ( *it ) = NULL;
- }
- cout << "clear this point vector" << endl;
- vecStudent.clear();
-
- return 0;
- }
#include "stdafx.h"
#include "vector"
#include "string"
#include "algorithm"
#include "iostream"
using namespace std;
class CStudent
{
public:
CStudent( int iHeight ) : m_nHeight( iHeight )
{
}
int GetHeight() const
{
return m_nHeight;
}
private:
int m_nHeight;
};
void vecDisplay( CStudent* pSt )
{
cout << "current value is : " << pSt->GetHeight() << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<CStudent *> vecStudent;
CStudent* CTest_A = new CStudent( 165 );
CStudent* CTest_B = new CStudent( 175 );
CStudent* CTest_C = new CStudent( 185 );
vecStudent.push_back( CTest_A );
vecStudent.push_back( CTest_B );
vecStudent.push_back( CTest_C );
cout << "Init vector : " << endl;
for_each( vecStudent.begin(), vecStudent.end(), vecDisplay );
vector<CStudent *>::iterator it;
for ( it = vecStudent.begin(); it != vecStudent.end(); it++ )
{
if ( NULL != ( *it ))
{
delete ( *it );
}
( *it ) = NULL;
}
cout << "clear this point vector" << endl;
vecStudent.clear();
return 0;
}
c、如果需要将某个对象保存到容器中,实际上STL会重新生成一个此对象的拷贝,然后将这个拷贝保存在容器中,源对象不再使用。所以,当要保存的对象中含有指针类型成员变量时,要为容器中的对
象实现拷贝构造函数和赋值操作符。
--------------------------------------------------------------
- #include "stdafx.h"
- #include "vector"
- #include "string"
- #include "algorithm"
- #include "iostream"
- using namespace std;
-
- class CStudent
- {
- public:
- CStudent( const char* strName, const int iHeight)
- {
- m_nHeight = iHeight;
- m_strName = new char[ strlen( strName + 1 ) ];
- strcpy( m_strName, strName );
- }
- CStudent( const CStudent& st )
- {
- m_nHeight = st.m_nHeight;
- m_strName = new char[ strlen( st.m_strName ) ];
- strcpy( m_strName, st.m_strName );
- }
- CStudent& operator= ( const CStudent& st )
- {
-
- if ( this == &st )
- {
- return *this;
- }
- m_nHeight = st.m_nHeight;
- m_strName = new char[ strlen( st.m_strName ) ];
- strcpy( m_strName, st.m_strName );
- return *this;
- }
- ~CStudent()
- {
- if ( NULL != m_strName )
- {
- delete[] m_strName;
- m_strName = NULL;
- }
- }
- char* GetName() const
- {
- return m_strName;
- }
- int GetHeight() const
- {
- return m_nHeight;
- }
- private:
- int m_nHeight;
- char* m_strName;
- };
-
- void vecDisplay( const CStudent st )
- {
- cout << "the student name is : " << st.GetName()<< endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
-
- vector<CStudent> vecStudent;
- CStudent Test_A( "zengraoli1", 155 );
- CStudent Test_B( "zengraoli2", 165 );
- CStudent Test_C( "zengraoli3", 175 );
-
- Test_A = Test_B;
- CStudent Test_D = Test_C;
-
- vecStudent.push_back(Test_A);
- vecStudent.push_back(Test_B);
- vecStudent.push_back(Test_C);
-
- cout << "output vector element : " << endl;
- for_each( vecStudent.begin(), vecStudent.end(), vecDisplay );
-
- return 0;
- }
#include "stdafx.h"
#include "vector"
#include "string"
#include "algorithm"
#include "iostream"
using namespace std;
class CStudent
{
public:
CStudent( const char* strName, const int iHeight)
{
m_nHeight = iHeight;
m_strName = new char[ strlen( strName + 1 ) ];
strcpy( m_strName, strName );
}
CStudent( const CStudent& st )
{
m_nHeight = st.m_nHeight;
m_strName = new char[ strlen( st.m_strName ) ];
strcpy( m_strName, st.m_strName );
}
CStudent& operator= ( const CStudent& st )
{
// to prevent self assignment
if ( this == &st )
{
return *this;
}
m_nHeight = st.m_nHeight;
m_strName = new char[ strlen( st.m_strName ) ];
strcpy( m_strName, st.m_strName );
return *this;
}
~CStudent()
{
if ( NULL != m_strName )
{
delete[] m_strName;
m_strName = NULL;
}
}
char* GetName() const
{
return m_strName;
}
int GetHeight() const
{
return m_nHeight;
}
private:
int m_nHeight;
char* m_strName;
};
void vecDisplay( const CStudent st )
{
cout << "the student name is : " << st.GetName()<< endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
// Init
vector<CStudent> vecStudent;
CStudent Test_A( "zengraoli1", 155 );
CStudent Test_B( "zengraoli2", 165 );
CStudent Test_C( "zengraoli3", 175 );
Test_A = Test_B; // Test_A已经构造过了,所以这时进入的事重载的=操作符
CStudent Test_D = Test_C; // Test_D没构造过,所以这时进入拷贝构造函数
vecStudent.push_back(Test_A);
vecStudent.push_back(Test_B);
vecStudent.push_back(Test_C);
cout << "output vector element : " << endl;
for_each( vecStudent.begin(), vecStudent.end(), vecDisplay );
return 0;
}
d、删除一个容器中大于某个数
删除的时候要注意:
如在for循环中加上it++,那么删除的时候会后移一个。可以不再for中写it++,而在else部分写
删除一个数的时候,不能仅仅是vecStudent.erase( it );必须要it = vecStudent.erase( it );记录,这是因为STL里的所有容器类中的erase实现都会返回一个迭代器,这个迭代器指向"当前删除
元素的后续元素,或者是end()"
--------------------------------------------------------------
- #include "stdafx.h"
- #include "vector"
- #include "string"
- #include "algorithm"
- #include "iostream"
- using namespace std;
-
- class CStudent
- {
- public:
- CStudent( int iHeight ) : m_nHeight( iHeight )
- {
-
- }
- int GetHeight() const
- {
- return m_nHeight;
- }
- private:
- int m_nHeight;
- };
-
- void vecDisplay( CStudent* pSt )
- {
- cout << "current value is : " << pSt->GetHeight() << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<CStudent *> vecStudent;
- CStudent* CTest_A = new CStudent( 165 );
- CStudent* CTest_B = new CStudent( 175 );
- CStudent* CTest_C = new CStudent( 185 );
- vecStudent.push_back( CTest_A );
- vecStudent.push_back( CTest_B );
- vecStudent.push_back( CTest_C );
-
- cout << "Init vector : " << endl;
- for_each( vecStudent.begin(), vecStudent.end(), vecDisplay );
-
-
- vector<CStudent *>::iterator it;
- for ( it = vecStudent.begin(); it != vecStudent.end(); )
- {
- if ( ( *it )->GetHeight() < 180 )
- {
- delete ( *it );
- ( *it ) = NULL;
- it = vecStudent.erase( it );
- }
- else
- {
- it++;
- }
- }
- cout << "\n";
- cout << "delete smaller then 180 : " << endl;
- for_each( vecStudent.begin(), vecStudent.end(), vecDisplay );
- return 0;
- }
怎样选择STL容器类型
vector : 需要保存大量数据的时候
map : 用来实现查找表,或者用来存储稀疏数组或稀疏矩阵
list : 频繁地对序列的中部进行插入和删除操作
deque : 当大部分插入和删除发生在序列的头部或尾部时
array : 固定长度的数组
STL算法
1)用for_each()算法遍历容器中的数据元素
for_each()的参数分别是开始位置、结束位置、处理函数
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
- #include "vector"
- #include "algorithm"
-
- void vecDisplay( const int iValue )
- {
- cout << "current value add 10 : " << iValue + 10 << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<int> vecSalary;
- vecSalary.push_back( 10 );
- vecSalary.push_back( 20 );
- vecSalary.push_back( 30 );
- vecSalary.push_back( 40 );
- vecSalary.push_back( 50 );
-
- cout << "display the value:" << endl;
- for_each( vecSalary.begin(), vecSalary.end(), vecDisplay );
-
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current value add 10 : " << iValue + 10 << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecSalary;
vecSalary.push_back( 10 );
vecSalary.push_back( 20 );
vecSalary.push_back( 30 );
vecSalary.push_back( 40 );
vecSalary.push_back( 50 );
cout << "display the value:" << endl;
for_each( vecSalary.begin(), vecSalary.end(), vecDisplay );
return 0;
}
2)用find算法实现线性查找-----判断容器中是否存在特定的数据
find()的参数分别是开始位置、结束位置、要查找的数据
- #include "stdafx.h"
- #include "vector"
- #include "algorithm"
- #include "string"
- #include "iostream"
- using namespace std;
-
- int _tmain(int argc, _TCHAR* argv[])
- {
-
- vector<string> vecStudentName;
- vecStudentName.push_back( "zengraoli" );
- vecStudentName.push_back( "125308501" );
- vecStudentName.push_back( "test" );
- vecStudentName.push_back( "find" );
-
- const string strFindName = "125308501";
- vector<string>::iterator it = find( vecStudentName.begin(), vecStudentName.end(), strFindName );
- if (vecStudentName.end() != it)
- {
- cout << "vecStudentName is exist this string 125308501 !" << endl;
- }
- it = find( vecStudentName.begin(), vecStudentName.end(), "125308502" );
- if ( vecStudentName.end() == it )
- {
- cout << "vecStudentName isn't exist this string 125308502 !" << endl;
- }
-
-
- return 0;
- }
#include "stdafx.h"
#include "vector"
#include "algorithm"
#include "string"
#include "iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> vecStudentName;
vecStudentName.push_back( "zengraoli" );
vecStudentName.push_back( "125308501" );
vecStudentName.push_back( "test" );
vecStudentName.push_back( "find" );
const string strFindName = "125308501";
vector<string>::iterator it = find( vecStudentName.begin(), vecStudentName.end(), strFindName );
if (vecStudentName.end() != it)
{
cout << "vecStudentName is exist this string 125308501 !" << endl;
}
it = find( vecStudentName.begin(), vecStudentName.end(), "125308502" );
if ( vecStudentName.end() == it )
{
cout << "vecStudentName isn't exist this string 125308502 !" << endl;
}
return 0;
}
3)用find_if()算法实现线性查找-----判断容器中是否存在指定范围的数据
find_if()的参数分别是开始位置、结束位置、所定义的要查找的条件(以bool(int)函数来表示)
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
- #include "algorithm"
- #include "vector"
-
- #define FIND_VALUE_TERMS 6
-
- bool isPass( int n )
- {
- return n >= FIND_VALUE_TERMS;
- }
-
- void vecDisplay( int iValue )
- {
- cout << "current container value is : " << iValue << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<int> vecScores;
- for ( int i = 1; i <= 10; i++ )
- {
- vecScores.push_back( i );
- }
-
- vector< int >::iterator it = vecScores.begin();
- do
- {
- it = find_if( it, vecScores.end(), isPass );
- if (it != vecScores.end())
- {
- cout << "meet the conditions : " << ( *it ) << endl;
- it++;
- }
- else
- {
- break;
- }
- } while (true);
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "algorithm"
#include "vector"
#define FIND_VALUE_TERMS 6
bool isPass( int n )
{
return n >= FIND_VALUE_TERMS;
}
void vecDisplay( int iValue )
{
cout << "current container value is : " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecScores;
for ( int i = 1; i <= 10; i++ )
{
vecScores.push_back( i );
}
vector< int >::iterator it = vecScores.begin();
do
{
it = find_if( it, vecScores.end(), isPass );
if (it != vecScores.end())
{
cout << "meet the conditions : " << ( *it ) << endl;
it++; // this iterator point next
}
else
{
break;
}
} while (true);
return 0;
}
4)用remove()实现移除、replace()实现替换
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
- #include "algorithm"
- #include "vector"
-
- #define FIND_VALUE_TERMS 6
-
- void vecDisplay( int iValue )
- {
- cout << "current container value is : " << iValue << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<int> vecScores;
- for ( int i = 1; i <= 10; i++ )
- {
- vecScores.push_back( i );
-
- }
-
- cout << "used function remove" << endl;
- const int removeValue = 8;
- remove( vecScores.begin(), vecScores.end(), removeValue );
- for_each( vecScores.begin(), vecScores.end(), vecDisplay );
-
- cout << "\n";
- cout << "used function replace" << endl;
- const int replaceValue = 9;
- const int newValue = 999;
- replace( vecScores.begin(), vecScores.end(),replaceValue, newValue );
- for_each( vecScores.begin(), vecScores.end(), vecDisplay );
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "algorithm"
#include "vector"
#define FIND_VALUE_TERMS 6
void vecDisplay( int iValue )
{
cout << "current container value is : " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecScores;
for ( int i = 1; i <= 10; i++ )
{
vecScores.push_back( i );
// vecScores.push_back( 9 );
}
cout << "used function remove" << endl;
const int removeValue = 8;
remove( vecScores.begin(), vecScores.end(), removeValue );
for_each( vecScores.begin(), vecScores.end(), vecDisplay );
cout << "\n";
cout << "used function replace" << endl;
const int replaceValue = 9;
const int newValue = 999;
replace( vecScores.begin(), vecScores.end(),replaceValue, newValue );
for_each( vecScores.begin(), vecScores.end(), vecDisplay );
return 0;
}
5)复制容器元素 : copy()
有时需要将一个容器中的元素复制到另一个容器中区,来完成数据的备份或者进行其他处理。
vector<float>::iterator lastPos在使用的时候,指向的是某个具体的数据而不是该数据的pos。
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
- #include "vector"
- #include "algorithm"
-
- void vecDisplay( const int iValue )
- {
- cout << "current container value is: " << iValue << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<float> vecScoreFirst;
- vector<float> vecScoreSecond;
- vector<float> vecScore;
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreFirst.push_back( 60.0f + i );
- }
- cout << "vecScoreFirst current value:" << endl;
- for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreSecond.push_back( 80.0f + i );
- }
- cout << "\n" << endl;
- cout << "vecScoreSecond current value:" << endl;
- for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
-
-
- vecScore.resize( vecScoreFirst.size() + vecScoreSecond.size() );
- vector< float >::iterator lastPos = copy( vecScoreFirst.begin(), vecScoreFirst.end(), vecScore.begin() );
- copy( vecScoreSecond.begin(), vecScoreSecond.end(), lastPos );
-
- cout << "\n" << endl;
- cout << "vecScore current value:" << endl;
- for_each( vecScore.begin(), vecScore.end(), vecDisplay );
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecScore;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 80.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
vecScore.resize( vecScoreFirst.size() + vecScoreSecond.size() ); // resize vecScore
vector< float >::iterator lastPos = copy( vecScoreFirst.begin(), vecScoreFirst.end(), vecScore.begin() );
copy( vecScoreSecond.begin(), vecScoreSecond.end(), lastPos );
cout << "\n" << endl;
cout << "vecScore current value:" << endl;
for_each( vecScore.begin(), vecScore.end(), vecDisplay );
return 0;
}
6)复制容器元素 : copy_backward()
从后向前覆盖
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
- #include "vector"
- #include "algorithm"
-
- void vecDisplay( const int iValue )
- {
- cout << "current container value is: " << iValue << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<float> vecScoreFirst;
- vector<float> vecScoreSecond;
- vector<float> vecScore;
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreFirst.push_back( 60.0f + i );
- }
- cout << "vecScoreFirst current value:" << endl;
- for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreSecond.push_back( 80.0f + i );
- }
- cout << "\n" << endl;
- cout << "vecScoreSecond current value:" << endl;
- for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
-
- cout << "\n" << endl;
- vecScore.resize( vecScoreFirst.size() + vecScoreSecond.size() );
- cout << "vecScore size is : " << vecScore.size() << endl;
-
- copy( vecScoreFirst.begin(), vecScoreFirst.end(), vecScore.begin() );
- copy_backward( vecScoreSecond.begin(), vecScoreSecond.end(), vecScore.end() );
-
- cout << "\n" << endl;
- cout << "vecScore current value:" << endl;
- for_each( vecScore.begin(), vecScore.end(), vecDisplay );
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecScore;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 80.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
cout << "\n" << endl;
vecScore.resize( vecScoreFirst.size() + vecScoreSecond.size() ); // resize vecScore
cout << "vecScore size is : " << vecScore.size() << endl;
copy( vecScoreFirst.begin(), vecScoreFirst.end(), vecScore.begin() );
copy_backward( vecScoreSecond.begin(), vecScoreSecond.end(), vecScore.end() );
cout << "\n" << endl;
cout << "vecScore current value:" << endl;
for_each( vecScore.begin(), vecScore.end(), vecDisplay );
return 0;
}
7)合并容器元素 : merge()
类似copy的用法
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
- #include "vector"
- #include "algorithm"
-
- void vecDisplay( const int iValue )
- {
- cout << "current container value is: " << iValue << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<float> vecScoreFirst;
- vector<float> vecScoreSecond;
- vector<float> vecResutl;
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreFirst.push_back( 60.0f + i );
- }
- cout << "vecScoreFirst current value:" << endl;
- for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreSecond.push_back( 60.0f + i );
- }
- cout << "\n" << endl;
- cout << "vecScoreSecond current value:" << endl;
- for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
-
-
-
- vecResutl.resize( vecScoreFirst.size() + vecScoreSecond.size() );
- merge( vecScoreFirst.begin(), vecScoreFirst.end(), vecScoreSecond.begin(), vecScoreSecond.end(), vecResutl.begin() );
-
- cout << "\n" << endl;
- cout << "vecScore current value:" << endl;
- for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecResutl;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 60.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
// used merge the two container must to pass through sort, otherwise error
vecResutl.resize( vecScoreFirst.size() + vecScoreSecond.size() );
merge( vecScoreFirst.begin(), vecScoreFirst.end(), vecScoreSecond.begin(), vecScoreSecond.end(), vecResutl.begin() );
cout << "\n" << endl;
cout << "vecScore current value:" << endl;
for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
return 0;
}
8)set_union()
合并之后去掉两个容器中重复的部分
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
- #include "vector"
- #include "algorithm"
-
- void vecDisplay( const int iValue )
- {
- cout << "current container value is: " << iValue << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<float> vecScoreFirst;
- vector<float> vecScoreSecond;
- vector<float> vecResutl;
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreFirst.push_back( 60.0f + i );
- }
- cout << "vecScoreFirst current value:" << endl;
- for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreSecond.push_back( 60.0f + i );
- }
- cout << "\n" << endl;
- cout << "vecScoreSecond current value:" << endl;
- for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
-
-
-
- vecResutl.resize( vecScoreFirst.size() + vecScoreSecond.size() );
- set_union( vecScoreFirst.begin(), vecScoreFirst.end(), vecScoreSecond.begin(), vecScoreSecond.end(), vecResutl.begin() );
-
- cout << "\n" << endl;
- cout << "vecScore current value:" << endl;
- for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecResutl;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 60.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
// used merge the two container must to pass through sort, otherwise error
vecResutl.resize( vecScoreFirst.size() + vecScoreSecond.size() );
set_union( vecScoreFirst.begin(), vecScoreFirst.end(), vecScoreSecond.begin(), vecScoreSecond.end(), vecResutl.begin() );
cout << "\n" << endl;
cout << "vecScore current value:" << endl;
for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
return 0;
}
9)transform()
在进行元素的复制时,同时对元素进行某些操作
transform有两种使用方式,分别对应的func参数不同
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
- #include "vector"
- #include "algorithm"
-
- #define ADD_VALUE 10
-
-
- int firstAddFunc( int iValue )
- {
- return iValue + ADD_VALUE;
- }
-
-
- int secondAddFunc( int iLeftValue, int iRightValue )
- {
- return iLeftValue + iRightValue;
- }
-
- void vecDisplay( int iValue )
- {
- cout << "current container value is: " << iValue << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<float> vecScoreFirst;
- vector<float> vecScoreSecond;
- vector<float> vecResutl;
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreFirst.push_back( 60.0f + i );
- }
- cout << "vecScoreFirst current value:" << endl;
- for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
-
- for ( int i = 0; i < 10; i++ )
- {
- vecScoreSecond.push_back( 80.0f + i );
- }
- cout << "\n" << endl;
- cout << "vecScoreSecond current value:" << endl;
- for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
-
-
- vecResutl.resize( vecScoreFirst.size() );
- transform( vecScoreFirst.begin(), vecScoreFirst.end(), vecResutl.begin(), firstAddFunc );
- cout << "\n" << endl;
- cout << "transform the first form vecScore current value:" << endl;
- for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
-
-
- vecResutl.clear();
- vecResutl.resize( vecScoreFirst.size() );
- transform( vecScoreFirst.begin(), vecScoreFirst.end(), vecScoreSecond.begin(), vecResutl.begin(), secondAddFunc );
- cout << "\n" << endl;
- cout << "transform the second form vecScore current value:" << endl;
- for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
#define ADD_VALUE 10
// used transform the first form
int firstAddFunc( int iValue )
{
return iValue + ADD_VALUE;
}
// used transform the first form
int secondAddFunc( int iLeftValue, int iRightValue )
{
return iLeftValue + iRightValue;
}
void vecDisplay( int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecResutl;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 80.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
// used transform the first form
vecResutl.resize( vecScoreFirst.size() );
transform( vecScoreFirst.begin(), vecScoreFirst.end(), vecResutl.begin(), firstAddFunc );
cout << "\n" << endl;
cout << "transform the first form vecScore current value:" << endl;
for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
// used transform the second form
vecResutl.clear();
vecResutl.resize( vecScoreFirst.size() );
transform( vecScoreFirst.begin(), vecScoreFirst.end(), vecScoreSecond.begin(), vecResutl.begin(), secondAddFunc );
cout << "\n" << endl;
cout << "transform the second form vecScore current value:" << endl;
for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
return 0;
}
10)sort()、reverse()
排序和翻转算法
- #include "stdafx.h"
- #include "string"
- #include "iostream"
- using namespace std;
- #include "vector"
- #include "algorithm"
-
- void vecDisplay( const string iValue )
- {
- cout << "current container value is: " << iValue << endl;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<string> vecStudentName;
- vector<string>::iterator it;
- vecStudentName.push_back( "zeng" );
- vecStudentName.push_back( "zengraoli" );
- vecStudentName.push_back( "zengRaoli" );
- vecStudentName.push_back( "test" );
- vecStudentName.push_back( "125308501" );
- vecStudentName.push_back( "zengRaoli2" );
- vecStudentName.push_back( "1zeng" );
-
- cout << "vecStudentName current value:" << endl;
- for( it = vecStudentName.begin(); it != vecStudentName.end(); it++ )
- {
- cout << "vecScore current value:" << ( *it ) << endl;
- }
-
-
- sort( vecStudentName.begin(), vecStudentName.end() );
- cout << "\n" << endl;
- cout << "pass sort vecStudentName current value:" << endl;
- for_each( vecStudentName.begin(), vecStudentName.end(), vecDisplay );
-
-
- reverse( vecStudentName.begin(), vecStudentName.end() );
- cout << "\n" << endl;
- cout << "pass reverse vecStudentName current value:" << endl;
- for_each( vecStudentName.begin(), vecStudentName.end(), vecDisplay );
-
- return 0;
- }
#include "stdafx.h"
#include "string"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const string iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> vecStudentName;
vector<string>::iterator it;
vecStudentName.push_back( "zeng" );
vecStudentName.push_back( "zengraoli" );
vecStudentName.push_back( "zengRaoli" );
vecStudentName.push_back( "test" );
vecStudentName.push_back( "125308501" );
vecStudentName.push_back( "zengRaoli2" );
vecStudentName.push_back( "1zeng" );
cout << "vecStudentName current value:" << endl;
for( it = vecStudentName.begin(); it != vecStudentName.end(); it++ )
{
cout << "vecScore current value:" << ( *it ) << endl;
}
// used sort algorithm
sort( vecStudentName.begin(), vecStudentName.end() );
cout << "\n" << endl;
cout << "pass sort vecStudentName current value:" << endl;
for_each( vecStudentName.begin(), vecStudentName.end(), vecDisplay );
// used reverse algorithm
reverse( vecStudentName.begin(), vecStudentName.end() );
cout << "\n" << endl;
cout << "pass reverse vecStudentName current value:" << endl;
for_each( vecStudentName.begin(), vecStudentName.end(), vecDisplay );
return 0;
}
更改对基本数据类型的sort算法:
- #include "stdafx.h"
- #include "string"
- #include "vector"
- #include "algorithm"
- #include "assert.h"
- #include "iostream"
- using namespace std;
-
- void vecDisplay( const int iValue )
- {
- cout << "current value is " << iValue << endl;
- }
-
-
- bool defineSort( const int iLeftValue, const int iRightValue )
- {
- return ( iLeftValue > iRightValue );
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<int> vecIValue;
- vecIValue.push_back( 9 );
- vecIValue.push_back( 1 );
- vecIValue.push_back( 3 );
- vecIValue.push_back( 5 );
- vecIValue.push_back( 8 );
- vecIValue.push_back( 7 );
- vecIValue.push_back( 2 );
-
-
-
-
-
-
-
- sort( vecIValue.begin(), vecIValue.end(), defineSort );
- cout << "pass sort : " << endl;
- for_each( vecIValue.begin(), vecIValue.end(), vecDisplay );
-
-
- return 0;
- }
#include "stdafx.h"
#include "string"
#include "vector"
#include "algorithm"
#include "assert.h"
#include "iostream"
using namespace std;
void vecDisplay( const int iValue )
{
cout << "current value is " << iValue << endl;
}
// my sort algorithm
bool defineSort( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecIValue;
vecIValue.push_back( 9 );
vecIValue.push_back( 1 );
vecIValue.push_back( 3 );
vecIValue.push_back( 5 );
vecIValue.push_back( 8 );
vecIValue.push_back( 7 );
vecIValue.push_back( 2 );
/*
sort( vecIValue.begin(), vecIValue.end() );
cout << "pass sort : " << endl;
for_each( vecIValue.begin(), vecIValue.end(), vecDisplay );
*/
sort( vecIValue.begin(), vecIValue.end(), defineSort );
cout << "pass sort : " << endl;
for_each( vecIValue.begin(), vecIValue.end(), vecDisplay );
return 0;
}
针对于自定义类型的sort算法
需要重写 < 号,暂时类里面不带有指针变量,否则还要重写拷贝构造
- #include "stdafx.h"
- #include "string"
- #include "vector"
- #include "algorithm"
- #include "assert.h"
- #include "iostream"
- using namespace std;
-
- namespace Zeng
- {
- class CTest_Rectang
- {
- public:
- CTest_Rectang( int iLong, int iWidth, int iHeight )
- : m_iLong( iLong ), m_iWidth( iWidth ), m_iHeight( iHeight )
- {
- }
- bool operator < ( const CTest_Rectang& rCTest_Rectang )
- {
- assert( rCTest_Rectang.m_iLong );
- if ( rCTest_Rectang.m_iLong > this->m_iLong )
- {
- return true;
- }
- return false;
- }
- friend void vecDisplay( const CTest_Rectang& rCTest_Rectang );
- private:
- int m_iLong;
- int m_iWidth;
- int m_iHeight;
- };
- void vecDisplay( const Zeng::CTest_Rectang& rCTest_Rectang )
- {
- cout << "current container Zeng::CTest_Rectang m_iLong is: " << rCTest_Rectang.m_iLong << endl;
- }
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<Zeng::CTest_Rectang> vecCTestRectang;
- for ( int i = 0; i < 8; i++ )
- {
- vecCTestRectang.push_back( Zeng::CTest_Rectang( 14 + i, 14, 14 ) );
- }
-
-
- sort( vecCTestRectang.begin(), vecCTestRectang.end() );
- cout << "\n" << endl;
- cout << "pass sort vecStudentName current value:" << endl;
- for_each( vecCTestRectang.begin(), vecCTestRectang.end(), Zeng::vecDisplay );
-
-
- reverse( vecCTestRectang.begin(), vecCTestRectang.end() );
- cout << "\n" << endl;
- cout << "pass reverse vecStudentName current value:" << endl;
- for_each( vecCTestRectang.begin(), vecCTestRectang.end(), Zeng::vecDisplay );
-
- return 0;
- }
#include "stdafx.h"
#include "string"
#include "vector"
#include "algorithm"
#include "assert.h"
#include "iostream"
using namespace std;
namespace Zeng
{
class CTest_Rectang
{
public:
CTest_Rectang( int iLong, int iWidth, int iHeight )
: m_iLong( iLong ), m_iWidth( iWidth ), m_iHeight( iHeight )
{
}
bool operator < ( const CTest_Rectang& rCTest_Rectang )
{
assert( rCTest_Rectang.m_iLong );
if ( rCTest_Rectang.m_iLong > this->m_iLong )
{
return true;
}
return false;
}
friend void vecDisplay( const CTest_Rectang& rCTest_Rectang );
private:
int m_iLong;
int m_iWidth;
int m_iHeight;
};
void vecDisplay( const Zeng::CTest_Rectang& rCTest_Rectang )
{
cout << "current container Zeng::CTest_Rectang m_iLong is: " << rCTest_Rectang.m_iLong << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<Zeng::CTest_Rectang> vecCTestRectang;
for ( int i = 0; i < 8; i++ )
{
vecCTestRectang.push_back( Zeng::CTest_Rectang( 14 + i, 14, 14 ) );
}
// used sort algorithm
sort( vecCTestRectang.begin(), vecCTestRectang.end() );
cout << "\n" << endl;
cout << "pass sort vecStudentName current value:" << endl;
for_each( vecCTestRectang.begin(), vecCTestRectang.end(), Zeng::vecDisplay );
// used reverse algorithm
reverse( vecCTestRectang.begin(), vecCTestRectang.end() );
cout << "\n" << endl;
cout << "pass reverse vecStudentName current value:" << endl;
for_each( vecCTestRectang.begin(), vecCTestRectang.end(), Zeng::vecDisplay );
return 0;
}
11)min_element()、max_element()
取最大最小值算法,容器需要经过sort排序
找到后输出后面的全部值
- #include "stdafx.h"
- #include "string"
- #include "vector"
- #include "algorithm"
- #include "assert.h"
- #include "iostream"
- using namespace std;
-
- void vecDisplay( const int iValue )
- {
- cout << "current value is " << iValue << endl;
- }
-
-
- bool defineSort( const int iLeftValue, const int iRightValue )
- {
- return ( iLeftValue > iRightValue );
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<int> vecIValue;
- vecIValue.push_back( 7 );
- vecIValue.push_back( 8 );
- vecIValue.push_back( 3 );
- vecIValue.push_back( 1 );
- vecIValue.push_back( 9 );
- vecIValue.push_back( 5 );
- vecIValue.push_back( 2 );
-
- vector<int>::iterator it;
- it = max_element( vecIValue.begin(), vecIValue.end() );
- for ( ; it != vecIValue.end(); it++ )
- {
- cout << "max_element current value is : " << ( *it ) << endl;
- }
-
- cout << "\n" << endl;
- it = min_element( vecIValue.begin(), vecIValue.end() );
- for ( ; it != vecIValue.end(); it++ )
- {
- cout << "min_element current value is : " << ( *it ) << endl;
- }
-
- return 0;
- }
#include "stdafx.h"
#include "string"
#include "vector"
#include "algorithm"
#include "assert.h"
#include "iostream"
using namespace std;
void vecDisplay( const int iValue )
{
cout << "current value is " << iValue << endl;
}
// my sort algorithm
bool defineSort( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecIValue;
vecIValue.push_back( 7 );
vecIValue.push_back( 8 );
vecIValue.push_back( 3 );
vecIValue.push_back( 1 );
vecIValue.push_back( 9 );
vecIValue.push_back( 5 );
vecIValue.push_back( 2 );
vector<int>::iterator it;
it = max_element( vecIValue.begin(), vecIValue.end() );
for ( ; it != vecIValue.end(); it++ )
{
cout << "max_element current value is : " << ( *it ) << endl;
}
cout << "\n" << endl;
it = min_element( vecIValue.begin(), vecIValue.end() );
for ( ; it != vecIValue.end(); it++ )
{
cout << "min_element current value is : " << ( *it ) << endl;
}
return 0;
}
函数指针
1)
根据函数指针所指向函数的不同,需要根据函数的具体声明来定义一个函数指针,其语法格式如下:
函数返回值类型标识符 ( 指针变量名 )( 形参列表 );
由于"()"的优先级高于"*",所以指针变量名外的括号必不可少。形参列表表示指针变量指向的函数所带的参数列表。
2)
例如有一个函数
void PrintPass( int iLeft, int iRightValue );
如果要声明一个函数指针
void ( *pFunc )( int iLeft, int iRightValue );
省略形参后
void ( *pFunc )( int, int );
如果要定义多个同一类型的指针,还可以使用typedef关键字定义一种新的函数之着呢的数据类型,用这种新的数据类型来定义函数指针,例如
// 定义一种新的函数指针的数据类型
typedef bool ( *pFunc )( int, int );
// 使用新的数据类型定义函数指针
pFunc pMax;
// 直接指向函数
pMax = Max;
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
-
- typedef bool ( *pFunc )( int, int );
-
- bool Max( const int iLeftValue, const int iRightValue )
- {
- return ( iLeftValue > iRightValue );
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- pFunc pMax;
- pMax = Max;
- cout << "pMax( 5, 6 ) this return bool value is : " << pMax( 5, 6 ) << endl;
- cout << "pMax( 6, 5 ) this return bool value is : " << pMax( 6, 5 ) << endl;
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
typedef bool ( *pFunc )( int, int );
bool Max( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
pFunc pMax;
pMax = Max;
cout << "pMax( 5, 6 ) this return bool value is : " << pMax( 5, 6 ) << endl;
cout << "pMax( 6, 5 ) this return bool value is : " << pMax( 6, 5 ) << endl;
return 0;
}
3)
可以在声明的时候不使用typedef直接用auto作为函数指针的数据类型来声明一个函数指针,
auto pMax = Max; // 只能在vs2010上面才使用有效
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
-
- int Max( const int iLeftValue, const int iRightValue )
- {
- return ( iLeftValue > iRightValue );
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- auto pMaxSendcont = Max;
- cout << "pMaxSendcont( 5, 6 ) this return bool value is : " << pMaxSendcont( 5, 6 ) << endl;
- cout << "pMaxSendcont( 6, 5 ) this return bool value is : " << pMaxSendcont( 6, 5 ) << endl;
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
int Max( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
auto pMaxSendcont = Max;
cout << "pMaxSendcont( 5, 6 ) this return bool value is : " << pMaxSendcont( 5, 6 ) << endl;
cout << "pMaxSendcont( 6, 5 ) this return bool value is : " << pMaxSendcont( 6, 5 ) << endl;
return 0;
}
用函数指针实现回调函数
1)
回调函数就是一个通过函数指针调用的函数。如果吧函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,就说这事回调函数。回调函数不是由该函数的实现方直接
调用,而是特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
2)
回调函数实现的机制是:
a、定义一个回调函数
b、提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者
c、当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理
3)为什么要使用回调函数
因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数
- #include "stdafx.h"
- #include "iostream"
- using namespace std;
-
- typedef bool ( *PMAXFUNC )( int, int );
-
- void PrintMessage( int iLeftValue, int iRightValue, PMAXFUNC pMax )
- {
- cout << "Print Header :" << endl;
- cout << "====================================================" << endl;
- cout << "pMax LeftValue is : " << iLeftValue << endl;
- cout << "pMax RightValue is : " << iRightValue << endl;
- cout << "pMax function return is : " << pMax( iLeftValue, iRightValue ) << endl;
- cout << "====================================================" << endl;
- cout << "Print ender :" << endl;
- }
-
- bool Max( const int iLeftValue, const int iRightValue )
- {
- return ( iLeftValue > iRightValue );
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- PMAXFUNC pMax = Max;
- PrintMessage( 5, 6, pMax );
-
- return 0;
- }
#include "stdafx.h"
#include "iostream"
using namespace std;
typedef bool ( *PMAXFUNC )( int, int );
void PrintMessage( int iLeftValue, int iRightValue, PMAXFUNC pMax )
{
cout << "Print Header :" << endl;
cout << "====================================================" << endl;
cout << "pMax LeftValue is : " << iLeftValue << endl;
cout << "pMax RightValue is : " << iRightValue << endl;
cout << "pMax function return is : " << pMax( iLeftValue, iRightValue ) << endl;
cout << "====================================================" << endl;
cout << "Print ender :" << endl;
}
bool Max( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
PMAXFUNC pMax = Max;
PrintMessage( 5, 6, pMax );
return 0;
}
4)将函数指针应用到STL算法中
ptr_fun()函数将一个普通函数指针转换为一个函数对象
bind1st()函数将整个函数对象的第一个参数绑定为nStandardHeigth
a、在count_if()算法中实现规则和统计标准的完全自定义:
- #include "stdafx.h"
- #include "vector"
- #include "string"
- #include "algorithm"
- #include "functional"
- #include "iostream"
- using namespace std;
-
- #define STANDARHEIGHT 165
- #define STUDENTNUM 5
-
- class CStudent
- {
- public:
- CStudent( int iHeight ) : m_iHeight( iHeight )
- {
- }
- int GetHeight() const
- {
- return m_iHeight;
- }
- private:
- int m_iHeight;
- };
-
- bool countHeight( int iHeight, const CStudent st)
- {
- return st.GetHeight() > iHeight;
- }
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<CStudent> vecStudent;
- for (int i = 0; i < STUDENTNUM; i++)
- {
- vecStudent.push_back( CStudent( STANDARHEIGHT - 10 + i * 10 ) );
- }
-
- const int nStandarHeight = STANDARHEIGHT;
- int iCount = count_if( vecStudent.begin(), vecStudent.end(), bind1st( ptr_fun( countHeight ), nStandarHeight ) );
-
- cout << "the student height greater than Standar Number is : " << iCount << endl;
-
- return 0;
- }
#include "stdafx.h"
#include "vector"
#include "string"
#include "algorithm"
#include "functional"
#include "iostream"
using namespace std;
#define STANDARHEIGHT 165
#define STUDENTNUM 5
class CStudent
{
public:
CStudent( int iHeight ) : m_iHeight( iHeight )
{
}
int GetHeight() const
{
return m_iHeight;
}
private:
int m_iHeight;
};
bool countHeight( int iHeight, const CStudent st)
{
return st.GetHeight() > iHeight;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<CStudent> vecStudent;
for (int i = 0; i < STUDENTNUM; i++)
{
vecStudent.push_back( CStudent( STANDARHEIGHT - 10 + i * 10 ) );
}
const int nStandarHeight = STANDARHEIGHT;
int iCount = count_if( vecStudent.begin(), vecStudent.end(), bind1st( ptr_fun( countHeight ), nStandarHeight ) );
cout << "the student height greater than Standar Number is : " << iCount << endl;
return 0;
}
bind1st()函数将整个函数对象的第一个参数绑定为nStandardHeigth,而函数对象的第二个参数就是iron国企中的CStudent对象作为参数调用countHeight()这个重新定义的统计规则函数,以实现
统计规则和统计标准的完全自定义。
b、在算法中使用指向某个类的成员函数的函数指针
- #include "stdafx.h"
- #include "vector"
- #include "string"
- #include "algorithm"
- #include "functional"
- #include "iostream"
- using namespace std;
-
- class CStudent
- {
- public:
- CStudent( string strName )
- {
- m_strName = strName;
- }
- bool isNamed( string strName )
- {
- return strName == m_strName;
- }
- private:
- string m_strName;
- };
-
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<CStudent> vecStudent;
- vecStudent.push_back( CStudent( "zengraoli1" ) );
- vecStudent.push_back( CStudent( "zengraoli2" ) );
- vecStudent.push_back( CStudent( "zengraoli3" ) );
-
- string strFindName = "zengraoli2";
- vector<CStudent>::iterator it = find_if( vecStudent.begin(), vecStudent.end(),
- bind2nd( mem_fun_ref( &CStudent::isNamed ), strFindName ) );
- if ( it != vecStudent.end() )
- {
- cout << "找到了对应的vecStudent!" << endl;
- }
-
- return 0;
- }
#include "stdafx.h"
#include "vector"
#include "string"
#include "algorithm"
#include "functional"
#include "iostream"
using namespace std;
class CStudent
{
public:
CStudent( string strName )
{
m_strName = strName;
}
bool isNamed( string strName )
{
return strName == m_strName;
}
private:
string m_strName;
};
int _tmain(int argc, _TCHAR* argv[])
{
vector<CStudent> vecStudent;
vecStudent.push_back( CStudent( "zengraoli1" ) );
vecStudent.push_back( CStudent( "zengraoli2" ) );
vecStudent.push_back( CStudent( "zengraoli3" ) );
string strFindName = "zengraoli2";
vector<CStudent>::iterator it = find_if( vecStudent.begin(), vecStudent.end(),
bind2nd( mem_fun_ref( &CStudent::isNamed ), strFindName ) );
if ( it != vecStudent.end() )
{
cout << "找到了对应的vecStudent!" << endl;
}
return 0;
}
在这段代码中,&CStudent::isNamed去的成员函数isNamed()的地址,也就是获得了指向这个成员函数的函数指针;然后使用mem_fun_ref()函数将这个函数指针构造成一个函数对象,如果容器中保存的是指向对象的指针,就应该使用mem_fun_ref()函数来完成这一任务。
因为这个成员函数需要一个蚕食,所以更进一步的,使用bind2nd()函数绑定其第二个参数strFindName来作为查找条件。因为这是一个类的成员函数指针,所以容器中的对象会作为默认隐含的第一个参数。
=====================================================================
函数指针配合STL算法的应用,将STL算法的通用性发挥到了极致。
函数对象
1)所谓函数对象,就是定义了函数调用操作符(function-call operator),即operator()的普通类的对象。在重载的函数调用操作符中,可以实现函数的所有功能。同事,因为类具有属性,可以将每次
函数调用的状态数据保存到他的属性中,这样函数对象就不会像函数指针那样失忆了,从而可以应用在更广的范围内。
2)定义一个模板函数对象
------------------------------------------------------
- template <typename T>
- class myMax
- {
- T operator()(T a, T b)
- {
- return ( a > b ? a : b );
- }
- };
template <typename T>
class myMax
{
T operator()(T a, T b)
{
return ( a > b ? a : b );
}
};
3)在STL中使用函数对象
------------------------------------------------------
- #include "stdafx.h"
- #include "vector"
- #include "algorithm"
- #include "iostream"
- using namespace std;
-
- namespace Zeng
- {
- class CStudent
- {
- public:
- CStudent( int nHeight ) : m_nHieght( nHeight )
- {
- }
- int GetHeight()
- {
- return m_nHieght;
- }
- private:
- int m_nHieght;
- };
-
- class CAverageHeight
- {
- public:
- CAverageHeight() : m_nCount( 0 ), m_nTotalHeight( 0 )
- {
- }
- void operator ()( CStudent st )
- {
- m_nTotalHeight += st.GetHeight();
- m_nCount++;
- }
- int GetCount()
- {
- return m_nCount;
- }
- int GetTotalHeight()
- {
- return m_nTotalHeight;
- }
- float GetAverageHeight()
- {
- if ( 0 != m_nCount )
- {
- return static_cast<float>( GetTotalHeight() / GetCount() );
- }
- return 0;
- }
- private:
- int m_nCount;
- int m_nTotalHeight;
- };
- }
-
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<Zeng::CStudent> vecStudent;
- vecStudent.push_back( Zeng::CStudent( 155 ) );
- vecStudent.push_back( Zeng::CStudent( 165 ) );
- vecStudent.push_back( Zeng::CStudent( 175 ) );
- vecStudent.push_back( Zeng::CStudent( 185 ) );
- vecStudent.push_back( Zeng::CStudent( 195 ) );
-
-
- Zeng::CAverageHeight ah;
-
- ah = for_each( vecStudent.begin(), vecStudent.end(), ah);
- cout << "average height is : " << ah.GetAverageHeight() << endl;
- cout << "the student count is : " << ah.GetCount() << endl;
-
- return 0;
- }
#include "stdafx.h"
#include "vector"
#include "algorithm"
#include "iostream"
using namespace std;
namespace Zeng
{
class CStudent
{
public:
CStudent( int nHeight ) : m_nHieght( nHeight )
{
}
int GetHeight()
{
return m_nHieght;
}
private:
int m_nHieght;
};
class CAverageHeight
{
public:
CAverageHeight() : m_nCount( 0 ), m_nTotalHeight( 0 )
{
}
void operator ()( CStudent st )
{
m_nTotalHeight += st.GetHeight();
m_nCount++;
}
int GetCount()
{
return m_nCount;
}
int GetTotalHeight()
{
return m_nTotalHeight;
}
float GetAverageHeight()
{
if ( 0 != m_nCount )
{
return static_cast<float>( GetTotalHeight() / GetCount() );
}
return 0;
}
private:
int m_nCount;
int m_nTotalHeight;
};
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<Zeng::CStudent> vecStudent;
vecStudent.push_back( Zeng::CStudent( 155 ) );
vecStudent.push_back( Zeng::CStudent( 165 ) );
vecStudent.push_back( Zeng::CStudent( 175 ) );
vecStudent.push_back( Zeng::CStudent( 185 ) );
vecStudent.push_back( Zeng::CStudent( 195 ) );
// use function object
Zeng::CAverageHeight ah;
// use function object in the stl algorithm
ah = for_each( vecStudent.begin(), vecStudent.end(), ah);
cout << "average height is : " << ah.GetAverageHeight() << endl;
cout << "the student count is : " << ah.GetCount() << endl;
return 0;
}
说明:在这里创建了一个函数对象ah并将它应用到for_each()算法中,for_each()算法会以容器中的每个Student对象为参数来对这个函数对象的"()"操作符进行调用。这时,函数对象自然就会将每个
Student对象的身高累加到它自己的m_nTotalHeight属性上,同事它还会记录已经统计过的对象数目。最后,for_each()算法会将完成统计后的函数对象作为结果返回,而这时的函数对象ah已经是一个保存了统计结果的函数对象了。通过函数对象提供的接口函数,可以轻松地获得统计结果并进行输出。
还可以这么用:
- #include "stdafx.h"
- #include "vector"
- #include "algorithm"
- #include "iostream"
- using namespace std;
-
- namespace Zeng
- {
- class CStudent
- {
- public:
- CStudent( int nHeight ) : m_nHieght( nHeight )
- {
- }
- int GetHeight()
- {
- return m_nHieght;
- }
- private:
- int m_nHieght;
- };
-
- class CAverageHeight
- {
- public:
- CAverageHeight() : m_nCount( 0 ), m_nTotalHeight( 0 )
- {
- }
- void operator ()( CStudent st )
- {
- m_nTotalHeight += st.GetHeight();
- m_nCount++;
- }
- operator float()
- {
- return GetAverageHeight();
- }
- operator int()
- {
- return GetCount();
- }
- int GetCount()
- {
- return m_nCount;
- }
- int GetTotalHeight()
- {
- return m_nTotalHeight;
- }
- float GetAverageHeight()
- {
- if ( 0 != m_nCount )
- {
- return static_cast<float>( GetTotalHeight() / GetCount() );
- }
- return 0;
- }
- private:
- int m_nCount;
- int m_nTotalHeight;
- };
- }
-
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<Zeng::CStudent> vecStudent;
- vecStudent.push_back( Zeng::CStudent( 155 ) );
- vecStudent.push_back( Zeng::CStudent( 165 ) );
- vecStudent.push_back( Zeng::CStudent( 175 ) );
- vecStudent.push_back( Zeng::CStudent( 185 ) );
- vecStudent.push_back( Zeng::CStudent( 195 ) );
-
-
- float fAverHeight = for_each( vecStudent.begin(), vecStudent.end(), Zeng::CAverageHeight() );
- cout << "average height is : " << fAverHeight << endl;
- int iCount = for_each( vecStudent.begin(), vecStudent.end(), Zeng::CAverageHeight() );
- cout << "average height is : " << iCount << endl;
- return 0;
- }