标签:opera list 基类 param 特性 not 支持 存在 特殊
用法参考示例
//申请一块指向单个int对象的内存, 并将值初始化为"5"
int *ptr_0 = new int(5);
//申请一块指向5个连续int类型对象的内存
//使用C++11统一的花括号初始化, 直观地对内存进行初始化
int * ptr_1 = new int[5]{1,2,3,4,5};
用法参考示例
//删除之前申请的内存
delete ptr_0;
//删除数组的写法, 注意
delete [] ptr_1;x
从本质上理解, 创建和销毁由编译器幕后控制, 程序员只能确保在本行代码有效的, 就是右值(包括立即数);
而用户创建的, 通过作用域规则可知其生存期的, 就是左值(包括函数返回的局部变量的引用以及const对象).
摘自博客
左值右值参考示例
int a{};
//下式中a是左值, 5+1会产生一个临时变量6, 是右值
a = 5+1;
左值引用参考示例
int var = 1;
int &ref = var; // 定义一个左值引用变量
ref = 2; // 通过左值引用修改引用内存的值
//以下语句会报错, 10不是一个合法的左值
//int &ref0 = 10;
//用const修饰, 常引用, 引用常量
const int &ref0 = 10;
//等价于下面两行代码
const int temp = 10;
const int &ref1 = temp;
右值引用参考示例
//右值引用
int && rref = 10;
右值引用实际应用参考
存在如下类定义
class C { public: //获得类C的一个实例 static C getObject() { return C(); } };
//这一行会调用类C的复制构造函数, 参数为getObject()函数产生的临时对象
//其后临时对象会调用析构函数销毁
C c = C::getObject();
//右值引用避免了一次中间临时变量的构造与析构过程
//引用直接指向函数返回时构造的对象
C &&rref = C::getObject();
一些技巧
- 当函数返回的内容在函数体外仍然存在的时候(通常是左值), 可以考虑返回引用以提升效率
- 而函数返回的内容在函数体外不能继续存在的时候(比如函数体中的局部变量, 或右值), 则可以在接受返回值时使用右值引用以提升效率
lambda表达式的语法形式
[捕获列表] (参数列表) 修饰信息 -> 返回值类型 {函数体}
[capture list] (params list) mutable exception-> return-type {function-body}
访问控制示例
class C
{
friend void fun0(C& c);//友元函数声明
public:
int pub;//公有成员
protected:
int pro;//保护成员
private:
int pri;//私有成员
};
void fun0(C& c)
{
c.pub;
c.pro;
c.pri;//没问题, 可以访问
}
class C_plus:public C//公有继承, 基类成员可见性不变
{
friend void fun2(C_plus &c);//友元函数声明
void fun1()
{
this->pub;
this->pro;
//this->pri;//报错, 不可访问
}
};
void fun2(C_plus& c)
{
c.pub;
c.pro;
//c.pri;//报错, 不可访问
}
典型实现
//"C"为类名
C();//一个无参构造函数
{
//do something
}
C(int a, int b)//一个接受两个int值的构造函数
{
//do something
}
典型实现
//"C"为类名
~C()
{
//do something
//通常情况下这里会有一些代码用来delete在构造函数中new出的内存指针
}
典型实现
//"C"为类名
C(const C & another)//必须使用引用作为参数; const可加可不加, 但建议加上
{
//do something
}
典型实现
//"C"为类名
C(C && another)
{
//do something
}
典型实现
//"C"为类名
C& operator=(const C &another)
{
//do something
return * this;
}
典型实现
//"C"为类名
C* operator&()
{
return this;//直接将地址返回
}
典型实现
//"C"为类名
const C* operator&() const
{
return this;//直接将地址返回
}
典型实现
class C
{
public:
int data;//成员变量
//类型转换构造函数, 将int类型的值转换为类对象
/*explicit */C(const int &_data)
{
this->data = _data;
}
}
类型转换函数
C++中, 类型的名字也是一种运算符, 即强制类型转换运算符
典型实现
class C
{
private:
int data;
public:
//转换函数(转换为int类型), 在需求int类型时传递C类的对象会自动调用
operator int(){ return data; }
}
即: 不允许修改this指针指向的对象; 不允许调用对象的非const成员函数
//类成员函数
void fun()const
{
//do something
}
//注:并没有下面这种写法, 只是本质上等价于下面的代码
//"C"为类名
//注意这里const是修饰类型C的
//这意味着this指针指向的内容被看作常量
void fun(const C * this)
{
//do something
}
//示例1
int a{};
//下面这一行语句的输出是"int"
cout << typeid(a).name();
存在如下类定义
class C0 { }; class C0_plus:public C0 { }; class C1 { protected: //虚函数 virtual ~C1() { } }; class C1_plus :public C1 { virtual ~C1_plus() { } };
//示例2
C0* p0 = new C0();
//下面的语句输出"class C0"
cout << typeid(*p0).name() << endl;
C0* p1 = new C0_plus();
//下面的语句输出"class C0"
cout << typeid(*p1).name() << endl;
//---------------------
C1* p3 = new C1();
//下面的语句输出"class C1"
cout << typeid(*p3).name() << endl;
C1* p4 = new C1_plus();
//下面的语句输出"class C1_plus"
cout << typeid(*p4).name() << endl;
C++11标准删除了auto关键字的传统用法. 现在, auto关键字用于自动类型推断
题外话
显而易见, auto执行的类型推断是在编译时完成的,不会对运行效率有任何影响.
同时, C++编译器在编译时本身也需要判断声明类型和实际类型是否匹配, 因此应该也不会影响编译速度 (就算影响了也不差这点, 扯远了)
auto类型推导可以用于模板, 用以省略模板参数类型的衍生类型在模板参数列表中的声明
本例摘自博客
//传统写法, 需要专门为makeObject()的返回值类型在模板的参数列表中添加一项
template <typename Product, typename Creator>
void processProduct(const Creator& creator) {
Product* val = creator.makeObject();
// do somthing with val
}
//使用auto的写法, 得到一定简化
template <typename Creator>
void processProduct(const Creator& creator) {
auto val = creator.makeObject();
// do somthing with val
}
传统上using关键字用于导入命名空间中的全部或者部分内容
比如:
using namespace std;//导入std命名空间中的所有内容
using std::cout;//只导入命名空间std中的cout
但在新的C++中, using可以用于取代typedef
虽然功能相同但(似乎)更加直观
//这一条语句为std::string取了一个别名"stdstring"
using stdstring = std::string;
可以用在类声明中
class C
{
public:
using uss = std::string;
typedef std::string tss;
};
还有个什么简化声明父类中成员函数的功能, 不是很了解, 到时候再写
标签:opera list 基类 param 特性 not 支持 存在 特殊
原文地址:https://www.cnblogs.com/Sirius-Z/p/12239485.html