C++_01_入门
一、类的定义
Person.h类声明
Person.cpp类实现
main.cpp主函数
二、命名空间的使用
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
Xcode格式化代码:快捷键ctrl + i
主函数:
三、类的继承
父类Person
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
子类Girl
Java PHP中使用关键定extends
c++中冒号表示继承,和Objective-C一样
冒号后面的public表示,继承过来的东东公开
主函数main.cpp
四、构造和析构方法
类Object
main.cpp主函数
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" style="color:rgb(57,57,57); font-family:'Courier New'; font-weight:bold; line-height:32px; background-color:rgb(245,245,245)">
五、运行父类的【构造方法】
父类Person
子类Girl
//调用父类的构造方法
cpp是通过冒号实现
// Java和Objective-C中是通过superkeyword
// PHP使用parentkeyword
main.cpp主函数
六、调用父类的方法
C++因为没有superkeyword,因此,通过【父类名::方法()】调用某个父类的方法
C++还能够指定调用哪一级父类的方法
// 因为c++没有superkeyword,所以调用父类的方法:用的是【父类名::方法()】
// 优点就是,无论有多少重继承,都能够通过父类名去指定调用某一级的父类的方法。
因此,比Java中的superkeyword要强大
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
父类Person
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
子类Girl
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
七、实函数、虚函数、纯虚函数、函数重载
C++中,因为父类和子类都实现了cry方法【实函数】,
因此,仅仅会调用父类的cry方法
假设,想要实现Java中的多态效果,
那么必须把【父类和子类】的cry方法所实用virtualkeyword声明为【虚函数】
另外,C++纯虚函数,类似Java中的抽象方法,由不同的子类去实现
父类Person
子类 Girl
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
main.cpp主函数
当父类和子类 都实现了【实函数cry】时的情况:直接调用父类的cry
当父类和子类的cryy方法都用【virtual】keyword声明时。
与Java多态一样,调用子类的方法
纯虚方法
// 纯虚函数,类似Java中的抽象方法,由不同的子类去实现
virtual
void hobby()=0;
八、C++中的类。假设全部方法全是纯虚函数,那么就是纯虚类;
相当于Java中的接口。因为C++本身支持多继承。因此,在使用时,尽量依照Java中的【单继承实现多接口原则】,将其它父类设计成【纯虚类】
九、函数重载,即名称一样,參数列表不同
C++的string类型 不用加*
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
十、运算符重载
//
重载 += 运算符
voidoperator+=(Point
other){
add(other);
};
返回值operator运算符(參数列表){};
通过对象实例(或结构体)訪问,使用【.】
通过指针訪问 使用【->】
Point类
主函数main.cpp
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
使用指针,->,解引用
十一、伪函数
像函数一样调用,但不是函数,实质为:类或结构体
优点:能够将一些代码段,当作 一个类的对象实例,进行传递;如:作为方法回调,
十三、C++引用 & 【经常使用于參数列表中】
避免不必要的内存拷贝操作
十四、C++友元类
作用:将类中private成员,公开给特定的类【友元类】
由于不太好操控,so,Java语言就没有此概念
C++中,訪问修饰符 默认就是:pravite
【在A类内部使用keywordfriend class Foo;】声明友元类
此时,Foo类就能够訪问A类中的私有成员(耦合度太高)
十七、文件操作
右击products,show in finder,能够看到输出的文本文件
使用ofstream输出到文件1.txt
使用ifstream读入debug文件夹下的1.txt
使用ifstream读入debug文件夹下的1.txt
stringbuf类 代表缓冲区;定义在头文件<sstream>中
<span style="font-size:14px;">//
// main.cpp
// 17_文件操作
//
// Created by beyond on 14-10-2.
// Copyright (c) 2014年 com.beyond. All rights reserved.
//
#include <iostream>
// 文件操作 引入头文件 fstrem 即文件流
#include <fstream>
// 使用stringbuf字符缓冲区
#include <sstream>
using namespace std;
void testOutput(){
// 关联1.txt
ofstream stream("1.txt");
stream<<"Hello Beyond";
// 最后一定要记得关闭流
stream.close();
std::cout << "\n >>>> end output<<<<\n";
}
void testReadOneChar(){
// 使用输入流
ifstream input("1.txt");
// 缓存
char c;
input>>c;
// 最后一定要记得关闭流
input.close();
printf("%c",c);
}
void testReadToConsole(){
// 使用输入流
ifstream input("1.txt");
// 缓存
stringbuf buf;
// 读入缓冲区
input>>&buf;
// 最后一定要记得关闭流
input.close();
std::cout << buf.str() << "\n >>>> end <<<<\n";
}
int main(int argc, const char * argv[])
{
// testOutput();
// testReadOneChar();
testReadToConsole();
return 0;
}</span>
十六、C++字符串
C++字符串包装成一个类 string;重载了运算符 += 仅仅能接收字符串
导入<sstream>后,能够使用类stringstream
它可连接不同类型的变量,
由于,它重载了运算符 <<
所以,能够连接不同类型
而且返回值是stream本身,因此,可连续<<
调用它str()方法,返回c++字符串
继续调用c_str()方法,返回C字符串
C++ API 參数在线地址
string类的c_str()方法
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
stringstream类
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
stringstream类的str()方法
十五、C++标准容器库container
注意迭代器是一个内部类,它的对象实例是一个指针,
在对list取value时,使用【*】解引用
在对map取key或value时,使用时【->】
list有序集合的使用和遍历
map字典的使用和遍历
为方便使用map,重载了操作符【】
C++API在线參考
十二、C++函数指针 仅仅是多了一个类型限定
void (Animal::*funcPointer)();
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
typedef void(Animal::*FuncPoint)();
定义一个类型,一个函数指针类型;
函数指针,指向的函数必须是Animal或它子类里面的函数,而且没有參数,返回值是void
相比較c中的函数指针,仅仅是多一个类型限定:必须是Animal或它子类里面的函数
通过线程+函数指针+sleep,达到延时3秒后运行目的
效果图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
main.cpp代码:
//
// main.cpp
// 12_函数指针_2_延时运行
//
// Created by beyond on 14-10-3.
// Copyright (c) 2014年 com.beyond. All rights reserved.
//
#include <iostream>
// 线程
#include <thread>
// sleep
#include <unistd.h>
// 使用命名空间
using namespace std;
// 提前声明类
class Animal;
// 定义一个类型,一个函数指针类型;函数指针,指向的函数 必须是Animal或它子类里面的函数,而且没有參数
// 相比較c中的函数指针,仅仅是多一个类型限定:必须是Animal或它子类里面的函数
typedef void(Animal::*FuncPoint)();
// 线程的构造方法 中用到的 參数:实质是一个要运行的函数 相当于线程启动后,要运行的任务,相当于Java中的run方法
void run(Animal *target,FuncPoint pointer,int delay){
// 线程启动后,真正的要运行的方法,任务代码
// 1.先sleep
sleep(delay);
// 2.运行target的pointer所指向的方法
// 先对函数指针 解引用后,取得函数体,通过对象target运行函数
(target->*pointer)();
};
// 定义一个延时运行 特定target的特定selector的函数
void perform_delay(Animal *target,FuncPoint pointer,int delay){
// 调用thread类 来运行target对象的 pointer所指向的方法,并延时delay秒
// 前一个參数 是要运行的方法,后面全是 填充方法的參数列表
thread t(run,target,pointer,delay);
// thread的join方法,会在线程被真正地全然运行后,才返回
t.join();
}
class Animal {
public:
// 定义一个成员变量 类型是一个函数指针
FuncPoint p;
};
// 继承自Animal
class Bird :public Animal{
public:
// 构造方法,在构造方法中,调用 成员方法
Bird(){
// 1、正常方式:能够直接调用成员方法
this->fly();
// 2、特殊方式:通过 一个函数指针,调用 成员方法...
// &Bird::fly表示 取成员方法的 地址
// (FuncPoint) 表示 强制转换成 一个函数指针类型
p = (FuncPoint)(&Bird::fly);
// 最后,通过函数指针,解引用 变成函数,通过this-> 调用 函数
(this->*p)();
// 3、延时3秒后 运行,自已的成员方法
FuncPoint point = (FuncPoint)(&Bird::fly);
perform_delay(this, point, 3);
}
// 成员方法
void fly(){
printf("我是一仅仅小小小小小鸟~\n");
};
};
int main(int argc, const char * argv[])
{
std::cout << ">>>> start <<<<\n";
Bird *b = new Bird();
delete b;
std::cout << ">>>> end <<<<\n";
return 0;
}
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
C++中的vector
vector类为内置数组提供了一种替代表示。与string类一样 vector 类是随标准 C++引入的标准库的一部分 。为了使用vector 我们必须包括相关的头文件 :
#include <vector>
使用vector有两种不同的形式。即所谓的数组习惯和 STL习惯。
一、数组习惯使用方法
1. 定义一个已知长度的 vector :
vector< int > ivec( 10 ); //类似数组定义int ia[ 10 ];
能够通过ivec[索引號] 来訪问元素
使用 if ( ivec.empty() ) 推断是否是空,ivec.size()推断元素个数。
2. vector的元素被初始化为与其类型相关的缺省值:算术和指针类型的缺省值是 0。对于class 类型,缺省值可通过调用这类的缺省构造函数获得,我们还能够为每一个元素提供一个显式的初始值来完毕初始化,比如
vector< int > ivec( 10, -1 );
定义了 ivec 它包括十个int型的元素 每一个元素都被初始化为-1
对于内置数组 我们能够显式地把数组的元素初始化为一组常量值,比如 :
int ia[ 6 ] = { -2, -1, 0, 1, 2, 1024 };
我们不能用相同的方法显式地初始化 vector ,可是能够将 vector 初始化为一个已有数组的所有或一部分,仅仅需指定希望被用来初始化 vector 的数组的開始地址以及数组最末元的下一位置来实现,比如:
// 把 ia 的 6 个元素复制到 ivec 中
vector< int > ivec( ia, ia+6 );
被传递给ivec 的两个指针标记了用来初始化对象的值的范围。第二个指针总是指向要拷贝的末元素的下一位置,标记出来的元素范围也能够是数组的一个子集,比如 :
// 拷贝 3 个元素 ia[2], ia[3], ia[4]
vector< int > ivec( &ia[ 2 ], &ia[ 5 ] );
3. 与内置数组不同 vector 能够被还有一个 vector 初始化 或被赋给还有一个 vector 比如
vector< string > svec;
void init_and_assign()
{
// 用还有一个 vector 初始化一个 vector
vector< string > user_names( svec );
// ...
// 把一个 vector 拷贝给还有一个 vector
svec = user_names;
}
二、STL习惯使用方法
在 STL9中对vector 的习惯使用方法全然不同。我们不是定义一个已知大小的 vector,而是定义一个空 vector
vector< string > text;
1. 我们向 vector 中插入元素。而不再是索引元素,以及向元素赋值,比如 push_back()操作,就是在 vector 的后面插入一个元素以下的 while 循环从标准输入读入一个字符串序列并每次将一个字符串插入到 vector 中
string word;
while ( cin >> word ) {
text.push_back( word );
// ...
}
尽管我们仍能够用下标操作符来迭代訪问元素
cout << "words read are: \n";
for ( int ix = 0; ix < text.size(); ++ix )
cout << text[ ix ] << ' ';
cout << endl;
可是 更典型的做法是使用 vector 操作集中的begin()和 end()所返回的迭代器 iterator
对 :
cout << "words read are: \n";
for ( vector<string>::iterator it = text.begin();
it != text.end(); ++it )
cout << *it << ' ';
cout << endl
iterator 是标准库中的类,它具有指针的功能
*it;
对迭代器解引用,并訪问其指向的实际对象
++it;
向前移动迭代器 it 使其指向下一个元素
2. 注意 不要混用这两种习惯使用方法。 比如,以下的定义
vector< int > ivec;
定义了一个空vector 再写这种语句
ivec[ 0 ] = 1024;
就是错误的 。由于 ivec 还没有第一个元素。我们仅仅能索引 vector 中已经存在的元素 size()操作返回 vector 包括的元素的个数 。
3. 类似地 当我们用一个给定的大小定义一个 vector 时,比如 :
vector<int> ia( 10 );
不论什么一个插入操作都将添加vector 的大小,而不是覆盖掉某个现有的元素。这看起来好像是非常显然的,可是 以下的错误在刚開始学习的人中并不少见 :
const int size = 7;
int ia[ size ] = { 0, 1, 1, 2, 3, 5, 8 };
vector< int > ivec( size );
for ( int ix = 0; ix < size; ++ix )
ivec.push_back( ia[ ix ]);
程序结束时ivec 包括 14 个元素, ia 的元素从第八个元素開始插入。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
Xcode格式化代码:快捷键ctrl + i
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
Java PHP中使用关键定extends
c++中冒号表示继承,和Objective-C一样
冒号后面的public表示,继承过来的东东公开
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" style="color:rgb(57,57,57); font-family:'Courier New'; font-weight:bold; line-height:32px; background-color:rgb(245,245,245)">
//调用父类的构造方法
cpp是通过冒号实现
// Java和Objective-C中是通过superkeyword
// PHP使用parentkeyword
C++还能够指定调用哪一级父类的方法
// 因为c++没有superkeyword,所以调用父类的方法:用的是【父类名::方法()】
// 优点就是,无论有多少重继承,都能够通过父类名去指定调用某一级的父类的方法。
因此,比Java中的superkeyword要强大
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
C++中,因为父类和子类都实现了cry方法【实函数】,
因此,仅仅会调用父类的cry方法
假设,想要实现Java中的多态效果,
那么必须把【父类和子类】的cry方法所实用virtualkeyword声明为【虚函数】
另外,C++纯虚函数,类似Java中的抽象方法,由不同的子类去实现
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
// 纯虚函数,类似Java中的抽象方法,由不同的子类去实现
virtual
void hobby()=0;
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
//
重载 += 运算符
voidoperator+=(Point
other){
add(other);
};
返回值operator运算符(參数列表){};
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
<span style="font-size:14px;">//
// main.cpp
// 17_文件操作
//
// Created by beyond on 14-10-2.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// #include <iostream>
// 文件操作 引入头文件 fstrem 即文件流
#include <fstream>
// 使用stringbuf字符缓冲区
#include <sstream> using namespace std; void testOutput(){
// 关联1.txt
ofstream stream("1.txt");
stream<<"Hello Beyond";
// 最后一定要记得关闭流
stream.close(); std::cout << "\n >>>> end output<<<<\n";
} void testReadOneChar(){
// 使用输入流
ifstream input("1.txt");
// 缓存
char c;
input>>c;
// 最后一定要记得关闭流
input.close();
printf("%c",c); }
void testReadToConsole(){
// 使用输入流
ifstream input("1.txt");
// 缓存
stringbuf buf;
// 读入缓冲区
input>>&buf;
// 最后一定要记得关闭流
input.close();
std::cout << buf.str() << "\n >>>> end <<<<\n";
}
int main(int argc, const char * argv[])
{
// testOutput();
// testReadOneChar();
testReadToConsole();
return 0;
}</span>
C++字符串包装成一个类 string;重载了运算符 += 仅仅能接收字符串
导入<sstream>后,能够使用类stringstream
它可连接不同类型的变量,
由于,它重载了运算符 <<
所以,能够连接不同类型
而且返回值是stream本身,因此,可连续<<
调用它str()方法,返回c++字符串
继续调用c_str()方法,返回C字符串
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
void (Animal::*funcPointer)();
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
typedef void(Animal::*FuncPoint)();
定义一个类型,一个函数指针类型;
函数指针,指向的函数必须是Animal或它子类里面的函数,而且没有參数,返回值是void
相比較c中的函数指针,仅仅是多一个类型限定:必须是Animal或它子类里面的函数
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
//
// main.cpp
// 12_函数指针_2_延时运行
//
// Created by beyond on 14-10-3.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// #include <iostream>
// 线程
#include <thread>
// sleep
#include <unistd.h>
// 使用命名空间
using namespace std;
// 提前声明类
class Animal;
// 定义一个类型,一个函数指针类型;函数指针,指向的函数 必须是Animal或它子类里面的函数,而且没有參数
// 相比較c中的函数指针,仅仅是多一个类型限定:必须是Animal或它子类里面的函数
typedef void(Animal::*FuncPoint)(); // 线程的构造方法 中用到的 參数:实质是一个要运行的函数 相当于线程启动后,要运行的任务,相当于Java中的run方法
void run(Animal *target,FuncPoint pointer,int delay){
// 线程启动后,真正的要运行的方法,任务代码
// 1.先sleep
sleep(delay);
// 2.运行target的pointer所指向的方法
// 先对函数指针 解引用后,取得函数体,通过对象target运行函数
(target->*pointer)();
}; // 定义一个延时运行 特定target的特定selector的函数
void perform_delay(Animal *target,FuncPoint pointer,int delay){
// 调用thread类 来运行target对象的 pointer所指向的方法,并延时delay秒
// 前一个參数 是要运行的方法,后面全是 填充方法的參数列表
thread t(run,target,pointer,delay);
// thread的join方法,会在线程被真正地全然运行后,才返回
t.join();
} class Animal {
public:
// 定义一个成员变量 类型是一个函数指针
FuncPoint p;
};
// 继承自Animal
class Bird :public Animal{
public:
// 构造方法,在构造方法中,调用 成员方法
Bird(){
// 1、正常方式:能够直接调用成员方法
this->fly();
// 2、特殊方式:通过 一个函数指针,调用 成员方法...
// &Bird::fly表示 取成员方法的 地址
// (FuncPoint) 表示 强制转换成 一个函数指针类型
p = (FuncPoint)(&Bird::fly);
// 最后,通过函数指针,解引用 变成函数,通过this-> 调用 函数
(this->*p)();
// 3、延时3秒后 运行,自已的成员方法
FuncPoint point = (FuncPoint)(&Bird::fly);
perform_delay(this, point, 3);
}
// 成员方法
void fly(){
printf("我是一仅仅小小小小小鸟~\n");
};
}; int main(int argc, const char * argv[])
{
std::cout << ">>>> start <<<<\n";
Bird *b = new Bird();
delete b; std::cout << ">>>> end <<<<\n";
return 0;
}
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
vector类为内置数组提供了一种替代表示。与string类一样 vector 类是随标准 C++引入的标准库的一部分 。为了使用vector 我们必须包括相关的头文件 :
#include <vector>
使用vector有两种不同的形式。即所谓的数组习惯和 STL习惯。
一、数组习惯使用方法
1. 定义一个已知长度的 vector :
vector< int > ivec( 10 ); //类似数组定义int ia[ 10 ];
能够通过ivec[索引號] 来訪问元素
使用 if ( ivec.empty() ) 推断是否是空,ivec.size()推断元素个数。
2. vector的元素被初始化为与其类型相关的缺省值:算术和指针类型的缺省值是 0。对于class 类型,缺省值可通过调用这类的缺省构造函数获得,我们还能够为每一个元素提供一个显式的初始值来完毕初始化,比如
vector< int > ivec( 10, -1 );
定义了 ivec 它包括十个int型的元素 每一个元素都被初始化为-1
对于内置数组 我们能够显式地把数组的元素初始化为一组常量值,比如 :
int ia[ 6 ] = { -2, -1, 0, 1, 2, 1024 };
我们不能用相同的方法显式地初始化 vector ,可是能够将 vector 初始化为一个已有数组的所有或一部分,仅仅需指定希望被用来初始化 vector 的数组的開始地址以及数组最末元的下一位置来实现,比如:
// 把 ia 的 6 个元素复制到 ivec 中
vector< int > ivec( ia, ia+6 );
被传递给ivec 的两个指针标记了用来初始化对象的值的范围。第二个指针总是指向要拷贝的末元素的下一位置,标记出来的元素范围也能够是数组的一个子集,比如 :
// 拷贝 3 个元素 ia[2], ia[3], ia[4]
vector< int > ivec( &ia[ 2 ], &ia[ 5 ] );
3. 与内置数组不同 vector 能够被还有一个 vector 初始化 或被赋给还有一个 vector 比如
vector< string > svec;
void init_and_assign()
{
// 用还有一个 vector 初始化一个 vector
vector< string > user_names( svec );
// ...
// 把一个 vector 拷贝给还有一个 vector
svec = user_names;
}
二、STL习惯使用方法
在 STL9中对vector 的习惯使用方法全然不同。我们不是定义一个已知大小的 vector,而是定义一个空 vector
vector< string > text;
1. 我们向 vector 中插入元素。而不再是索引元素,以及向元素赋值,比如 push_back()操作,就是在 vector 的后面插入一个元素以下的 while 循环从标准输入读入一个字符串序列并每次将一个字符串插入到 vector 中
string word;
while ( cin >> word ) {
text.push_back( word );
// ...
}
尽管我们仍能够用下标操作符来迭代訪问元素
cout << "words read are: \n";
for ( int ix = 0; ix < text.size(); ++ix )
cout << text[ ix ] << ' ';
cout << endl;
可是 更典型的做法是使用 vector 操作集中的begin()和 end()所返回的迭代器 iterator
对 :
cout << "words read are: \n";
for ( vector<string>::iterator it = text.begin();
it != text.end(); ++it )
cout << *it << ' ';
cout << endl
iterator 是标准库中的类,它具有指针的功能
*it;
对迭代器解引用,并訪问其指向的实际对象
++it;
向前移动迭代器 it 使其指向下一个元素
2. 注意 不要混用这两种习惯使用方法。 比如,以下的定义
vector< int > ivec;
定义了一个空vector 再写这种语句
ivec[ 0 ] = 1024;
就是错误的 。由于 ivec 还没有第一个元素。我们仅仅能索引 vector 中已经存在的元素 size()操作返回 vector 包括的元素的个数 。
3. 类似地 当我们用一个给定的大小定义一个 vector 时,比如 :
vector<int> ia( 10 );
不论什么一个插入操作都将添加vector 的大小,而不是覆盖掉某个现有的元素。这看起来好像是非常显然的,可是 以下的错误在刚開始学习的人中并不少见 :
const int size = 7;
int ia[ size ] = { 0, 1, 1, 2, 3, 5, 8 };
vector< int > ivec( size );
for ( int ix = 0; ix < size; ++ix )
ivec.push_back( ia[ ix ]);
程序结束时ivec 包括 14 个元素, ia 的元素从第八个元素開始插入。
C++_01_入门的更多相关文章
- hadoop_学习_01_入门准备
一.入门准备 1.零基础学习Hadoop 2.大数据初学者应该知道的知识
- GEF入门实例_总结_01_教程、源码、开发环境准备
一.前言 最近在学Eclipse插件开发,发现了一个比较好的GEF入门教程,并且按照教程上的操作,一步步实现了一个入门Demo,在此感谢作者的贡献. 好记性不如烂笔头,故决定总结一下这段时间的学习心得 ...
- 工控随笔_10_西门子_WinCC的VBS脚本_01_基础入门
很多人都认为VB语言或者VBS脚本语言是一种很low的语言,从心里看不起VB或者VBS, 但是其实VBS不仅可以做为系统管理员的利器,同样在工控领域VBS语言大有用武之地. 西门子的WinCC提供了两 ...
- RabbitMQ入门_01_简介与安装
A. 资源与参考文档 官网:https://www.rabbitmq.com/ B. 学习目的 部门目前使用其他部门维护的 WebLogic 的 JMS 消息服务,缺乏足够的技术支持与运维支持.随着基 ...
- Java_脚本引擎_01_用法入门
一.前言 最近有个需求,需要在js中调用java,这样能避免更新java,从而实现代码的热更新. 于是想到用 Nashorn JavaScript 引擎. 二.概述 通过 JDK 8 的 Nashor ...
- 工控随笔_C#连接PLC_之_C#入门_01_配置学习环境
最近在做一个东西,需要用到通用开发语言开发一个软件来读取PLC的内容,这方面的难点在于解析PLC利用 以太网通讯的通讯协议,而一般的PLC厂商对自己的协议是封闭的,对一般的开发者是不开放的,虽然可以通 ...
- GEF入门实例_总结_03_显示菜单和工具栏
一.前言 本文承接上一节: GEF入门实例_总结_02_新建初始RCP空项目 这一节,我们来给我们的插件加上菜单. 二.基础知识 1.action bar.menubar.coolbar 含义 a ...
- GEF入门实例_总结_02_新建初始RCP空项目
一.前言 本节承接上一节: GEF入门实例_总结_01_教程.源码.开发环境准备 这一节我们来创建一个空的RCP项目. 二.新建RCP项目 1. New 一个 Plug-in Project 2.输入 ...
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
随机推荐
- 揭秘Amazon反应速度超快的下拉菜单
揭秘Amazon反应速度超快的下拉菜单 如果你以前觉得Amazon这家公司不太在用户体验上下功夫,这篇文章可能会改变你的看法. Amazon主页的左上角有一个商品分类浏览的下拉菜单.当鼠标从菜单中的选 ...
- Windows系统中使用WMI获取远程服务器的信息
使用WMI获取远程服务器的状态 我做的项目里边主要包含两个内容: (1)对发布在服务器上的服务(IIS服务.WCF服务)是否可以正常访问: (2)获取服务器上的部分指标:如CPU.内存.磁盘空间信息等 ...
- hdu1114小猪抢劫银行
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1114 完全背包 题意:给出小猪钱罐的重量和装满钱后的重量,然后是几组数据,每组数据包括每种钱币的价值与重量 ...
- A Byte of Python 笔记(8)
第10章 解决问题——编写一个 python 脚本 程序功能:为所有重要文件创建备份 设计: 1.需要备份的文件和目录由一个列表指定 2.备份应该保存在主备份目录中 3.文件备份称一个 zip 文件 ...
- 网上下载的“上下3D”和“左右3D”影片该如何播放?
我们平常买的红蓝3D眼镜智能播放红蓝3D片源.网上找3D电影的时候,虽试图去找红蓝3D格式电影,但总会找到不少“左右格式”或者"上下格式"影片.正常播放后发现有两重画面.这种3D电 ...
- Android平台APK分析工具包androguard的部署使用和原理分析
原创文章,转载请注明出处,谢谢. Android应用程序分析主要有静态分析和动态分析两种,常见的静态分析工具是Apktool.dex2jar以及jdgui.今天突然主要到Google code上有个叫 ...
- UV印刷
UV就是在一张印上你想要的图案上面过上一层油,主要是增加产品亮度,保护产品表面,其硬度高,耐腐蚀摩擦,不易出现划痕等,有些复膜产品现改为上UV,能达到环保要求,但UV产品不易粘接,有些只能通过局部UV ...
- Spring Boot使用Redis进行消息的发布订阅
今天来学习如何利用Spring Data对Redis的支持来实现消息的发布订阅机制.发布订阅是一种典型的异步通信模型,可以让消息的发布者和订阅者充分解耦.在我们的例子中,我们将使用StringRedi ...
- android搭建环境错误 daemon not running. starting it now on port 5037 ADB server didn't ACK
android搭建环境错误 daemon not running. starting it now on port 5037 ADB server didn't ACK ADB server didn ...
- python Unicode转ascii码的一种方法
缘起 看到这样的数据:Marek Čech.Beniardá怎样变成相对应的ascii码呢 解决 import unicodedata s = u"Marek Čech" #(u表 ...