cpp笔记06

cpp new features

1-NULL、nullptr、constexptr

NULL是进行了宏定义的
#define NULL 0
nullptr也是0但是指针类型
constexptr常量表达式,其后跟的内部不支持函数条件判断

void func(char* p) 
{
printf ('' char \n'') ;
}

void func(int np) 
{
printf ('' int \n'') ;
}
int main() 
{
char* p = NULL;
func (p) ;//输出 int
func(nullptr) ;//输出char
return 0;
}

程序编译期时,为确定的变量,如数组长度确定,分配内存空间
程序运行期时,程序中的变量在栈上开辟内存空间,进行赋值等运算

#define LENGTH 10
int func1() 
{
return 10;
}
constexptr int func2() //constexptr常量表达式
{
return 10;
}
int main() 
{
int LEN = 5;
int arr1[LEN];//可以
int arr2[len];//不行,数组在编译期就分配内存,而len在运行期才会被赋值
int arr3[func1()+1];//不行,同上类似
int arr4[func2()+1];//可行
return 0;
}

2-迭代器和auto类型推导

#include<vector>
std::vector<int> vec;
... 
std::vector<int>::iterator it;//迭代器,返回的是指针
for(it= vec. begin() ; it != vec. end(); it++) 
{...}
for(std::vector<int>::iterator it2= vec. begin() ; it2 != vec. end(); it2++) 
{...}
for(auto it3= vec. begin() ; it3 != vec. end(); it3++) 
{...}
std::list<std::string> lt;
... 
for(std::string str:lt) 
{
std::cout << str. c_str() <<std::endl;
}
for(auto str:lt) 
{
std::cout << str. c_str() <<std::endl;
}

3-委托构造、继承构造

  • 委托构造
class c_base
{
public:
int m_num1;
int m_num2;
c_base() 
{
m_num1 = 1;
}
c_base(int n) : c_base () //委托c_base() 这个无参构造函数来帮助构造初始化,:后跟一个函数
{
m_num2 = n;
}
private:
int m_num1;
int m_num2;
};
  • 继承构造
class c_child : public  c_base
{
public:
using c_base::c_base;//使用父类的构造
};

int main () 
{
c_child child(10) ;
return 0;
}

4-关键字override、final、delete、default

  • override
    子类使用override关键字重写对应虚函数,要在父类中确实存在对应虚函数
    父类:
    virtual int func() ;
    子类:
    int func() override
    {…}

  • final
    对于类,希望当前的类不被其它类继承
    class c_child2 final : public c_base
    {…};
    对于虚函数,希望当前类的虚函数不被子类重写
    父类:
    virtual int func() final
    { }

  • default、delete
    这两个关键字也可以用于其它函数,大概用法如下所示

class c_obj
{
public:
c_obj() = default;//使用默认构造
c_obj() = delete;//禁止使用默认构造
c_obj(int n) 
{}
};

5-强制转换

  • const_cast
    去除变量的const属性,指对于,指针、引用、this指针
int n=7;
int* kp = const_cast<int*>(&n) ;
int& kp1 = const_cast<int&>(n) ;

前面提到过类中有常成员函数,在其中想要修改私有成员变量的操作是使用const_cast 去除this指针的类型(const T* const)中前面的const属性,再修改:

const_cast<c_base* const>(this)->m_num = 10;//<>中是要强转为的类型
  • static_cast
    类似于隐式转换
    k = static_cast(m) ;//基本数据类型和void*指针,类指针(父类转子类不安全)
    可以用于转换运算符
class c_base
{
public:
operator int()
{
return m_num;
} 
private:
int m_num;
};
int main() 
{
c_base obj;
int n = static_cast<int>(obj) ;//obj调用operator int() 返回int值,即把类强转为int 赋值给n
return 0;
}
  • dynamic_cast
    用于具有虚函数的基类与派生类之间的指针或引用的转换,不必要不使用,会增加额外函数开销。需要使用运行时类型信息(RTTI) ,其中涉及虚表,所以最后在向下转换(父类指针转子类)时使用
    父类指针转子类指针,不安全但使用static_cast不会报错,所以可以使用dynamic_cast检查
pSon = dynamic_cast <pParent*>(pParent) ;
if(pSon == nullptr) 
{
std::cout << '' 父类指针转子类指针不安全'' << std::endl;
}
  • reinterpret_cast
    类似于显示强转
    T1, T2为数据类型
T2 n = interpret_cast<T1>(m) ;
T2* n = interpret_cast<T1*>(m) ;

6-匿名函数

lambda表达式也是匿名函数,属于函数式编程,多用于多线程并发
在这里插入图片描述

int c;
c = [ ](int a, int b) ->int{return (a+ b);}(1,2); 

上面的lambda 函数即写即用,末尾的(1,2) 就是参数输入;
可以这样:

auto func = [ ](int a, int b) ->int{
return (a+ b);
}

这样就可以调用了,使用时
int d = func(2,3) ;
另一种:

auto func1 = [ ](int a){
return [ ](int b) {
return (a+ b);
}
}
int d = func1(2) (3) ;//分开给输入参数
  • mutable
    lambda表达式可以按函数的理解,外部a传入时是按值传递,在函数内留有同名的变量的拷贝,这里用a_表示,这个a_在函数体内的类型可认为是静态,想在内部修改就要用前面也提到过的mutable关键字,不加在函数内不能进行++a的运算;
int a = 10;
auto func = [ ](int a)mutable{
return ++a;
}
auto func2 = [ ](int a)mutable{
return ++a;
}
cout << func() << endl;//11
cout << func2() << endl;//11
cout << func() << endl;//12
cout << func2() << endl;//12
cout << a << endl;//10
两lambda表达式中a不相互影响,再次进入时保留了上次的值;
  • 捕获列表[ ]
    捕获列表[ ]未显示说明捕获方式时的捕获是在lambda表达式声明处之前的变量,进行按值传递参数,在表达式之后,无论是参数被修改还是func() 形式调用都不影响表达式内的数值,可认为执行即写即用时开始捕获之后或输出或调用的操作不影响函数内部参数值;
    有按值传递就会有按引用传递,[&a]就表示按引用捕获a,之后a改变lambda表达式内部也会变;
    [&a]按引用捕获a
    [a]按值捕获a
    [&]按引用捕获外部所在范围所有变量
    [=]按值捕获外部所在范围所有变量
    [a,b,&c]按值捕获a, b按引用捕获c
vector<int > vec = {1,2,3,4,5,6};
for_each(vec.begin(),vec.end(),[&](int n){
if(n%2 == 0) cout<< n <<''是偶数''<<endl;
cout << n <<''是奇数''<<endl;
}) ;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值