Xcode格式化程式碼:快捷鍵ctrl + i
Java PHP中使用關鍵定extends
c++中冒號表示繼承,和Objective-C一樣
冒號後面的public表示,繼承過來的東東公開
//呼叫父類的構造方法 cpp是通過冒號實現
// Java和Objective-C中是通過superkeyword
// PHP使用parentkeyword
C++還能夠指定呼叫哪一級父類的方法
// 因為c++沒有superkeyword,所以呼叫父類的方法:用的是【父類名::方法()】
// 優點就是,無論有多少重繼承,都能夠通過父類名去指定呼叫某一級的父類的方法。
因此,比Java中的superkeyword要強大
C++中,因為父類和子類都實現了cry方法【實函式】,
因此,僅僅會呼叫父類的cry方法
假設,想要實現Java中的多型效果,
那麼必須把【父類和子類】的cry方法所實用virtualkeyword宣告為【虛擬函式】
另外,C++純虛擬函式,類似Java中的抽象方法,由不同的子類去實現
// 純虛擬函式,類似Java中的抽象方法,由不同的子類去實現
virtual void hobby()=0;
// 過載 += 運算子
voidoperator+=(Point other){
add(other);
};
返回值operator運算子(引數列表){};
<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字串void (Animal::*funcPointer)();
typedef void(Animal::*FuncPoint)();
定義一個型別,一個函式指標型別;
函式指標,指向的函式必須是Animal或它子類裡面的函式,而且沒有引數,返回值是void
相比較c中的函式指標,僅僅是多一個型別限定:必須是Animal或它子類裡面的函式
//
// 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;
}
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 的元素從第八個元素開始插入。