C++11笔记(1)

1.类型推导 auto
以前我们类型声明总是要明确的指出所定义的变量类型,但是有的类型就比较冗长,比如 :std::map<int, std::string>::const_iterator itr = m.find(1);
前面的类型又长又不好写
所以我们现在可以使用auto来替代类型,而编译器会自己推导出该变量的类型。

int main()
{
	auto i = 10;
	auto j = 10.2;
	auto k = 3.2f;
	auto c = 'c';
	auto* p = &i;

	return 0;
}

比如这样,尽管我们没有写出i,j,k,c与p是什么类型,但是编译器会通过他初始化的值来推导出他们相应的类型。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在vs2015中我们可以将鼠标悬停在变量上就可以知道他是什么类型。

2.foreach循环
以前我们定义了一个vector容易或者数组的话,我们要变量的时候是定义一个下标,然后通过下标或者指针来遍历,这样我们总是要定义不比要的变量,而且代码也不简洁,现在我们可以这样。

int main()
{
	vector<int> v;
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(8);
	v.push_back(9);

	for (int value : v)
	{
		cout << value << endl;
	}
	return 0;
}

在这里插入图片描述
原理是对v中的每一个元素进行遍历,然后将元素赋给value,然后通过输出value来将v的每一个元素输出。

3.using代替typedef
在C/C++中,我们经常通过typedef来定义类型的别名,比如我们可以把unsigned int用typedef改为UINT,typedef unsigned int UINT;
这时候我们使用UINT就相当于是在使用unsigned int。
但我们现在有一个更加直观的写法,就是使用using ,using UINT=unsigned int;
这样我们可以很清晰的看出来UINT就相当于是unsigned int。

4.空指针nullptr
在以前我们定义指针的时候,我们会在指针还未有明确的指向时对其赋空也就是
int* p=NULL,但是NULL是一个宏定义。
在这里插入图片描述
我们可以看见NULL的本质是0,类型为int,但是我们并不希望这样,我们想要一个专门的指针类型的值来表示指针为空,所以就有了nullptr,以后我们就可以写int* p=nullptr。nullptr就是一个专门用来表示指针空的值。

5.强类型枚举 enum class
例:

enum Direction {  
	    Left, Right  
	};  
	enum Answer {  
	    Right, Wrong  
	};  

这个枚举类型中都有一个叫Right的值,但是他们俩所表示的含义却不相同,第一个Right表示的是方向右,第二个Right表示的是正确,并且他们俩的值也是不同地,第一个为1,第二个为0。
这样的话我们在使用的时候就会产生问题,到底我们的Right是表示的方向呢还是正确呢,这时候就说不清了。
所以我们有了强类型枚举,其实就是将枚举类型写在类里。

enum class Direction {  
    Left, Right  
};  
  
enum class Answer {  
    Right, Wrong  
};  
  
auto a = Direction::Left;  
	auto b = Answer::Right;  
	  
	if (a == b)  
	    std::cout << "a == b" << std::endl;  
	else  
	    std::cout << "a != b" << std::endl;  

这样子我们就可以很清楚的看出来想要用的Right究竟是哪一个。

6.构造函数的相互调用
例:

class A
{
private:
    int x;
    int y;
    std::string name;
public:
	A(int x,int y,string& name)
	:x(x),y(y),name(name)
	{}
	A(int x,int y)
	:A(x,y,"A")
	{}
	A()
	:A(0,0)
	{}
};

通过上面的例子我们可以看到,当类A构造一个无参对象时会调用无参构造函数,这时在其初始化列表里会调用一次双参构造函数,并且传了两个默认值上去,然后双参构造函数在初始化列表里调用了三参构造函数,并且加了一个默认值,这时候三参构造函数就会完成所有任务,成功定义出一个类对象。

7.禁止重写 final
例:

class A {  
	public:  
	    virtual void f1() final {}  
	};  
	  
	class B : public A {  
	    virtual void f1() {}  
	};  

这时候代码会报错,提示不能重写f1。

8.显式声明重写 override
例:

class A {  
public:  
    virtual void f1() const {}  
};  
  
class B : public A {  
    virtual void f1() {}  
}; 


	/*上面的代码在重写函数f1时不小心漏了const,但是编译器不会报错。因为它不知道你是要重写f1,而认为你是定义了一个新的函数。这样的情况也发生在基类的函数签名变化时,子类如果没有全部统一改过来,编译器也不能发现问题。
	C++ 11引入了override声明,使重写更安全。*/	

class B : public A {
		    virtual void f1() override {}
	
};
此时编译报错,提示找不到重写的函数。
 

   class B : public A {
    		    virtual void f1()const  override {}
    	
    };
    这时候就对了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值