C++特性学习

1.explicit关键字

        explicit关键字只需用于类内的单参数构造函数前面。由于无参数的构造函数和多参数的构造函数总是显示调用,这种情况在构造函数前加explicit无意义。google的c++规范中提到explicit的优点是可以避免不合时宜的类型变换,缺点无。所以google约定所有单参数的构造函数都必须是显示的,只有极少数情况下拷贝构造函数可以不声明称explicit。例如作为其他类的透明包装器的类。
  effective c++中说:被声明为explicit的构造函数通常比其non-explicit兄弟更受欢迎。因为它们禁止编译器执行非预期(往往也不被期望)的类型转换。除非我有一个好理由允许构造函数被用于隐式类型转换,否则我会把它声明为explicit,鼓励大家遵循相同的政策。

链接:https://www.cnblogs.com/rednodel/p/9299251.html

2.std::move()

std::move函数可以以非常简单的方式将左值引用转换为右值引用。

(左值、左值引用、右值、右值引用 参见:http://www.cnblogs.com/SZxiaochun/p/8017475.html

通过std::move,可以避免不必要的拷贝操作。

std::move是为性能而生。

std::move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝。

#include <iostream>
#include <utility>
#include <vector>
#include <string>
int main()
{
    std::string str = "Hello";
    std::vector<std::string> v;
    //调用常规的拷贝构造函数,新建字符数组,拷贝数据
    v.push_back(str);
    std::cout << "After copy, str is \"" << str << "\"\n";
    //调用移动构造函数,掏空str,掏空后,最好不要使用str
    v.push_back(std::move(str));
    std::cout << "After move, str is \"" << str << "\"\n";
    std::cout << "The contents of the vector are \"" << v[0]
                                         << "\", \"" << v[1] << "\"\n";
}

链接:https://www.cnblogs.com/SZxiaochun/p/8017349.html

3. std::numeric_limits

  • 在C/C++11中,std::numeric_limits为模板类,在库编译平台提供基础算术类型的极值等属性信息,取代传统C语言,所采用的预处理常数。比较常用的使用是对于给定的基础类型用来判断在当前系统上的最大值、最小值。
  • <limits>:头文件

  • 原型:
template <class T> numeric_limits;
  •  测试:
#include "numeric_limits.hpp"
#include <limits>
#include <iostream>
 
//
/* reference:
	http://www.cplusplus.com/reference/limits/numeric_limits/
	https://msdn.microsoft.com/en-us/library/c707ct0t.aspx
*/
int test_numeric_limits_1()
{
	std::cout << std::boolalpha;
	std::cout << "Minimum value for int: " << std::numeric_limits<int>::min() << std::endl;
	std::cout << "Maximum value for int: " << std::numeric_limits<int>::max() << std::endl;
	std::cout << "int is signed: " << std::numeric_limits<int>::is_signed << std::endl;
	std::cout << "Non-sign bits in int: " << std::numeric_limits<int>::digits << std::endl;
	std::cout << "int has infinity: " << std::numeric_limits<int>::has_infinity << std::endl;
 
	std::cout << "Minimum value for float: " << std::numeric_limits<float>::min() << std::endl; // min returns the smallest positive value the type can encode, not the lowest
	std::cout << "Lowest value for float: " << std::numeric_limits<float>::lowest() << std::endl; // the lowest value
	std::cout << "Maximum value for float: " << std::numeric_limits<float>::max() << std::endl;
	std::cout << "float is signed: " << std::numeric_limits<float>::is_signed << std::endl;
	std::cout << "Non-sign bits in float: " << std::numeric_limits<float>::digits << std::endl;
	std::cout << "float has infinity: " << std::numeric_limits<float>::has_infinity << std::endl;
 
	std::cout << "Minimum value for unsigned short: " << std::numeric_limits<unsigned short>::min() << std::endl;
	std::cout << "Maximum value for unsigned short: " << std::numeric_limits<unsigned short>::max() << std::endl;
 
	std::cout << "is_specialized(float): " << std::numeric_limits<float>::is_specialized << std::endl;
	std::cout << "is_integer(float): " << std::numeric_limits<float>::is_integer << std::endl;
	std::cout << "is_exact(float): " << std::numeric_limits<float>::is_exact << std::endl;
	std::cout << "is_bounded(float): " << std::numeric_limits<float>::is_bounded << std::endl;
	std::cout << "is_modulo(float): " << std::numeric_limits<float>::is_modulo << std::endl;
	std::cout << "is_iec559(float): " << std::numeric_limits<float>::is_iec559 << std::endl;
	std::cout << "digits10(float): " << std::numeric_limits<float>::digits10 << std::endl;
	std::cout << "radix(float): " << std::numeric_limits<float>::radix << std::endl;
	std::cout << "min_exponent(float): " << std::numeric_limits<float>::min_exponent << std::endl;
	std::cout << "max_exponent(float): " << std::numeric_limits<float>::max_exponent << std::endl;
	std::cout << "min_exponent10(float): " << std::numeric_limits<float>::min_exponent10 << std::endl;
	std::cout << "max_exponent10(float): " << std::numeric_limits<float>::max_exponent10 << std::endl;
	std::cout << "epsilon(float): " << std::numeric_limits<float>::epsilon() << std::endl;
	std::cout << "round_style(float): " << std::numeric_limits<float>::round_style << std::endl;
 
	std::cout << "The smallest nonzero denormalized value for float: "
		<< std::numeric_limits<float>::denorm_min()<< std::endl;
	std::cout << "The difference between 1 and the smallest value greater than 1 for float: "
		<< std::numeric_limits<float>::epsilon()<< std::endl;
	std::cout << "Whether float objects allow denormalized values: "
		<< std::numeric_limits<float>::has_denorm << std::endl;
	std::cout << "Whether float objects can detect denormalized loss: "
		<< std::numeric_limits<float>::has_denorm_loss << std::endl;
	std::cout << "Whether float objects have quiet_NaN: "
		<< std::numeric_limits<float>::has_quiet_NaN << std::endl;
	std::cout << "Whether float objects have a signaling_NaN: "
		<< std::numeric_limits<float>::has_signaling_NaN << std::endl;
	std::cout << "The base for type float is:  "
		<< std::numeric_limits<float>::radix << std::endl;
	std::cout << "The maximum rounding error for type float is:  "
		<< std::numeric_limits<float>::round_error() << std::endl;
	std::cout << "The rounding style for a double type is: "
		<< std::numeric_limits<double>::round_style << std::endl;
	std::cout << "The signaling NaN for type float is:  "
		<< std::numeric_limits<float>::signaling_NaN() << std::endl;
	std::cout << "Whether float types can detect tinyness before rounding: "
		<< std::numeric_limits<float>::tinyness_before << std::endl;
	std::cout << "Whether float types have implemented trapping: "
		<< std::numeric_limits<float>::traps << std::endl;
 
	return 0;
}

参考链接:https://blog.csdn.net/fengbingchun/article/details/77922558

4.friend友元

 友元可以是一个函数,该函数被称为友元函数;友元也可以是一个,该类被称为友元类。

特点:

  1. 能够访问类中的私有成员受保护的成员非成员函数
  2. 它与普通函数一样,即在定义上和调用上与普通函数一样
  3. 需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend

缺点:

  1. 破坏了程序的封装性。

注意事项:

  1. 友元关系是单向的
  2. 友元关系不能被传递
  3. 友元关系不能被继承
  • 友元函数 
#include <math.h>
#include <iostream>
using namespace std;
class Point
{
    friend double Distance(const Point &p1, const Point &p2);
public:
    Point(int x, int y);
private:
    int x_;
    int y_;
};
Point::Point(int x, int y) : x_(x), y_(y)
{
}
double Distance(const Point &p1, const Point &p2)
{
    double dx = p1.x_ - p2.x_;
    double dy = p1.y_ - p2.y_;
    return sqrt(dx * dx + dy * dy);
}
int main(void)
{
    Point p1(3, 4);
    Point p2(6, 9);
    cout << Distance(p1, p2) << endl;
    return 0;
}

类成员函数可以声明为其他类中的友元 

class B;
class A {
public:
 int Func1( B& b );
private:
 int Func2( B& b );
};
class B {
private:
 int _b;
 // A::Func1 is a friend function to class B
 // so A::Func1 has access to all members of B
 friend int A::Func1( B& );
};
int A::Func1( B& b ) { return b._b; } // OK

 

  • 友元类
#include <iostream>

using namespace std;
class YourClass {
friend class YourOtherClass; // Declare a friend class
public:
 YourClass() : topSecret(0){}
 void printMember() { cout << topSecret << endl; }
private:
 int topSecret;
};

class YourOtherClass {
public:
 void change( YourClass& yc, int x ){yc.topSecret = x;}
};

int main() {
 YourClass yc1;
 YourOtherClass yoc1;
 yc1.printMember();
 yoc1.change( yc1, 5 );
 yc1.printMember();
}

友元关系不能继承,这意味着从 YourOtherClass 派生的类不能访问 YourClass 的私有成员。友元关系不可传递,因此 YourOtherClass 的友元类无法访问 YourClass 的私有成员。 

参考:https://www.jb51.net/article/78440.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火柴的初心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值