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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值