C++ 基礎知識複習 1


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(&currentTime);
   cout << currentTime << endl;
   cout << localtime(&currentTime) << endl;
   cout << asctime(gmtime(&currentTime)) << 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章