C++ 基礎
1. mutable
#include <iostream>
using namespace std;
class MyClass {
mutable int i;
int j;
public:
int geti() const {
return i; // ok
}
void seti(int x) const {
i = x; // ok
}
/* 下面這個函數則編譯不通過
void setj(int x) const {
j = x; // 錯
}
*/
};
int main()
{
MyClass ob;
ob.seti(1900);
cout << ob.geti();
return 0;
}
2. 變長參數
cstdarg
#include <cstdarg>
#include <iostream>
using namespace std;
template <typename T>
T summary(int count, ...) {
T total = 0;
va_list list;
va_start(list, count);
for (int i = 0; i < count; ++i) {
total = total + va_arg(list, T);
}
va_end(list);
return total;
}
int main(int argc, char *argv[])
{
// 注意,這兒輸入的參數必須是double, 也就是必須要是1.0 而不是1
double result = summary<double>(4, 1.0, 2.0, 3.0, 4.5);
cout << result << endl;
return 0;
}
3. time
ctime
std::time_t time( std::time_t* arg);
time函數 返回當前時間,並將其轉碼爲time_t對象,然後將之存在參入傳入的對象中,除非arg是一個空指針。
也可以寫作 time_t time = time(NULL);
錯誤時,返回(std::time_t)(-1)
std::tm* localtime( const std::time_t *time );
localtime函數 將傳入的time轉換爲本地時間。
std::tm* gmtime(const std::time_t* time);
gmtime函數 將傳入的time轉換爲UTC時間。
char* asctime(const std::tm* time_ptr);
asctime函數 將傳入的時間轉換爲格式爲 Www Mmm dd hh:mm:ss yyyy\n 的字符串
e.g. 1462102142 -> Sun May 1 19:26:59 2016
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
time_t currentTime;
time(¤tTime);
cout << currentTime << endl;
cout << localtime(¤tTime) << endl;
cout << asctime(gmtime(¤tTime)) << endl;
return 0;
}
4. C++11新特性
4.1 lambda
[函數對象參數] (操作符重載函數參數)->返回值類型{ 函數體 }
- [a] 值傳遞
- [&a] 引用傳遞
- [=] 所有外部變量
- 默認const, 可以加mutable
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vi{1, 2, 3, 4, 5};
for_each(vi.begin(), vi.end(), [](int v) { cout << v << endl;});
int a = 5; int b = 6;
for_each(vi.begin(), vi.end(), [a](int v) { cout << v+a << endl;});
for_each(vi.begin(), vi.end(), [=](int v) { cout << (double)(v+a)/b << endl;});
return 0;
}
4.2 auto & decltype
auto實際上實在編譯時對變量進行了類型推導,所以不會對程序的運行效率造成不良影響。
另外,似乎auto並不會影響編譯速度,因爲編譯時本來也要右側推導然後判斷與左側是否匹 配。
auto a; // 錯誤,auto是通過初始化表達式進行類型推導,如果沒有初始化表達式,就無法確定a的類型
auto i = 1;
auto d = 1.0;
auto str = "Hello World";
auto ch = 'A';
auto func = less<int>();
vector<int> iv;
auto ite = iv.begin();
auto p = new foo() // 對自定義類型進行類型推導
在模板中的應用,
// 當我們沒有auto時 我們可能需要這樣寫
template <typename Product, typename Creator>
void processProduct(const Creator& creator) {
Product* val = creator.makeObject();
...
}
// with auto
template <typename Creator>
void processProduct(const Creator& creator) {
auto val = creator.makeObject();
...
}
decltype: 實際上有點像auto的反函數,auto可以讓你聲明一個變量,而decltype則可以從一個 變量或表達式中得到類型,
int x = 3;
decltype(x) y = x;
4.3 nullptr
nullptr是爲了解決原來C++中NULL的二義性問題而引進的一種新的類型.
#include <cstdlib>
#include <cassert>
#include <iostream>
using namespace std;
void F(int a) {
cout<<a<<endl;
}
void F(int *p) {
assert(p != NULL);
cout << p << endl;
}
int main(){
int *p = nullptr;
int *q = NULL;
bool equal = ( p == q ); // equal的值爲true,說明p和q都是空指針
int a = nullptr; // 編譯失敗,nullptr不能轉型爲int
cout << equal << endl;
F(0); // 在C++98中編譯失敗,有 義性;在C++11中調 F(int) F(nullptr);
return 0;
}
4.4 序列for循環
可用於數組 容器 和 string
map<string, int> m{{"a", 1}, {"b", 2}, {"c", 3}};
for (auto p : m){
cout << p.first << " : " << p.second << endl;
}
5. 利用tuple返回變長數據
/**
* tuple: 一種可以存放多個不同種類元素的多元組
* 例如: auto t = make_tuple(1, 2.0, "C++ 11", {1, 0, 2});
* make_tuple(): 創建tuple對象
* tie(): 創建一個tuple,其中的值是參數的引用
* get(): 從tuple提取元素
**/
#include <tuple>
#include <iostream>
#include <string>
#include <stdexcept>
std::tuple<double, char, std::string> get_student(int id)
{
if (id == 0) return std::make_tuple(3.8, 'A', "Lisa Simpson");
if (id == 1) return std::make_tuple(2.9, 'C', "Milhouse Van Houten");
if (id == 2) return std::make_tuple(1.7, 'D', "Ralph Wiggum");
throw std::invalid_argument("id");
}
int main()
{
auto student0 = get_student(0);
std::cout << "ID: 0, "
<< "GPA: " << std::get<0>(student0) << ", "
<< "grade: " << std::get<1>(student0) << ", "
<< "name: " << std::get<2>(student0) << '\n';
double gpa1;
char grade1;
std::string name1;
std::tie(gpa1, grade1, name1) = get_student(1);
std::cout << "ID: 1, "
<< "GPA: " << gpa1 << ", "
<< "grade: " << grade1 << ", "
<< "name: " << name1 << '\n';
}
輸出
ID: 0, GPA: 3.8, grade: A, name: Lisa Simpson
ID: 1, GPA: 2.9, grade: C, name: Milhouse Van Houten