AOP(Aspect-Oriented Programming,面向方面编程),可以解决面向对象编程中的一些问题, 是OOP的一种有益补充。面向对象编程中的继承是一种从上而下的关系,不适合定义从左到右的横向 关系,如果继承体系中的很多无关联的对象都有一些公共行为,这些公共行为可能分散在不同的组件, 不同的对象之中,通过继承方式提取这些公共行为就不太合适了。使用AOP还有一种情况是为了提高 程序的可维护性,AOP将程序的非核心逻辑都“横切”出来,将非核心逻辑和核心逻辑分离,使我们能 集中精力在核心逻辑上。
| |
—————- Logging
| |
Cross-cutting concerns
| |
—————- Security
| |
业务流程1 业务流程2
图1-1 AOP通过“横切”分离关注点
在上图1-1中,每个业务流程都有日志和权限验证的功能,还有可能增加新的功能,实际上我们只关心 核心逻辑,其他的一些附加逻辑,如日志和权限不需要关注,这时,就可以将日志和权限等非核心逻辑 “横切”出来,使核心逻辑尽可能的保持简洁和清晰,方便维护。这样“横切”的另一个好处是,这些公共 的非核心逻辑被提取到多个切面中了,使它们可以被其它组件或对象复用,消除了重复代码。
AOP把软件系统分为了两个部分:核心关注点和横切关注点。业务处理的流程是核心关注点,与之关系不 大是横切关注点。横切关注点的一个特点是,它们经常发生在核心关注点的多处,而各处基本相似,比如 权限认证、日志处理、事务处理。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点 分离开来。
C++11增加了一个新的类型,称为右值引用(R-value reference),标记为T&&。在介绍右值引用类型之前要了解什么是左值 和右值。左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象。一个区分左值和右值的 便捷方法是:看能不能对表达式取地址,如果能,则为左值,否则为右值。所有具名变量或对象都是左值,而右值不具名。 具体左右和右值请参考左值和右值;
在C++11中,右值由两个概念构成,一个是将亡值(xvalue,expiring value),另一个则是纯右值(prvalue,PureRvalue), 比如,非引用返回的临时变量、运算表达式产生的临时变量、原始字面量和lambda表达式等都是纯右值。而将亡值是C++11新增的、 与右值引用相关的表达式,比如,将要被移动的对象、T&&函数返回值、std::move返回值和转换为T&&的类型的转换函数的返回值。
C++11中所有的值必属于左值、将亡值、纯右值三者之一,将亡值和纯右值都属于右值。区分表达式的左右值属性有一个简便方法: 若可对表达式用&取地址符,则为左值、否则为右值。
int i = 0;
在这条语句中,i是左值,0是字面量,就是右值。在上面的代码中,i可以被引用,0就不可以了。字面量都是右值。
右值引用就是对一个右值进行引用的类型。因为右值不具名,所以我们只能通过引用的方式找到它。
无论声明左值引用还是右值引用都必须立即进行初始化,因为引用类型本身并不拥有所绑定对象的内存, 只是该对象的一个别名。通过右值引用的声明,该右值又“重获新生”,其生命周期与右值引用类型变量 的生命周期一样,只要该变量还活着,该右值临时变量将会一只存活下去。
#include<iostream>
using namespace std;
int g_constructCount = 0;
int g_copyConstructCount = 0;
int g_destructCount = 0;
struct A
{
A()
{
cout << "construct: " << ++g_constructCount << endl;
}
A(const A& a)
{
cout << "copy construct: " << ++g_copyConstructCount << endl;
}
~A()
{
cout << "destuct: " << ++g_destructCount << endl;
}
};
A GetA()
{
return A();
}
int main()
{
A a = GetA();
return 0;
}
为了清楚地观察临时值,在GCC下编译时设置编译选项-fno-elide-constructors
来关闭返回值优化效果
g++ rvalueReference.cpp –std=c++11 -fno-elide-constructors
输出结果:
construct: 1
copy construct: 1
destuct: 1
copy construct: 2
destuct: 2
destuct: 3
从上面的例子中可以看到,在没有返回值优化的情况下,拷贝构造函数调用了两次,一次是Get()函数内部创建的 对象返回后构造一个临时对象产生的,另一次是在mian函数中构造a对象产生的。第二次的destruct是因为临时 对象在构造a对象之后就销毁了。如果开启返回值优化,输出结果将是: g++ rvalueReference.cpp –std=c++11
construct: 1
destuct: 1
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
auto x = 5;
std::cout << typeid(x).name() << std::endl;
auto pi = new auto(1);
std::cout << typeid(pi).name() << std::endl;
const auto *v = &x, u = 6;
std::cout << typeid(v).name() << std::endl;
std::cout << typeid(u).name() << std::endl;
static auto y = 0.0;
std::cout << typeid(y).name() << std::endl;
// auto int r; // error
// auto s; // error
return 0;
}
output:
int
int *
int const *
int
double
#include <iostream>
#include <typeinfo>
int main()
{
int x = 0;
const auto *v = &x, u = 6.0;
std::cout << typeid(v).name() << std::endl;
std::cout << typeid(u).name() << std::endl;
return 0;
}
output:
autoTest.cpp: In function ‘int main()’:
autoTest.cpp:7:29: error: inconsistent deduction for ‘const auto’: ‘int’ and then ‘double’
const auto *v = &x, u = 6.0;
#include <iostream>
#include <typeinfo>
int main()
{
int x = 0;
auto *a = &x;
std::cout << typeid(a).name() << std::endl;
auto b = &x;
std::cout << typeid(b).name() << std::endl;
auto &c = x;
std::cout << typeid(c).name() << std::endl;
auto d = c;
std::cout << typeid(d).name() << std::endl;
const auto e = x;
std::cout << typeid(e).name() << std::endl;
auto f = e;
std::cout << typeid(f).name() << std::endl;
const auto &g = x;
std::cout << typeid(g).name() << std::endl;
auto &h = g;
std::cout << typeid(h).name() << std::endl;
}
output:
int *
int *
int
int
int
int
int
int
#include <iostream>
#include <typeinfo>
void func(auto a = 1) {} // error:auto 不能用于函数参数
struct Foo
{
auto var1_ = 0; // error:auto 不能用于非静态成员函数
static const auto var2_ = 0;
};
template <typename T>
sturct Bar{};
int main()
{
int arr[10] = { 0 };
auto aa = arr;
auto rr[10] = arr; // error
Bar<int> bar;
Bar<auto> bb = bar; // error
return 0
}
参考: 理解C和C++中的左值和右值
十年之前的数次回眸,铸就了我们一辈子的缘分。十年后的今天,
我们相知相恋并步入婚姻的殿堂。话说婚姻如坟墓,外面的恐惧,
里面的人想逃离,可我偏偏却是有不同的感受。我期待结婚,期待新娘
是你。其实,我这个人真的是缺点很多,比如没有收拾,邋遢,但是你都没有
抱怨啥,还不停的鞭策我,我真的是很幸运,能携手与你走完余生。
不知道什么时候心中不再是一个人,不知道什么时候心中多了一份牵挂
...但是我知道这一切的一切那都是因为你,现在的我下班就只想早早的回家,
回家吃你做的饭,和你聊天,看电视,哪怕是坐在你身旁刷手机都觉得是
满满的幸福。我觉得现在的我不能离开你超过一天,如果下班回家看不见你
就觉得心里没有着落,大脑一片空白,不知道干啥,这也许是依赖,但是,
我觉得这就是爱,一份平平淡淡的爱。说实话我们在相处了大概一年了,结婚
也有半年了,我对你一次生气都没有,有时候我真是生自己的气,但是都被你
误解了,你是如此的可爱,善良,我真没有那个勇气去惹你生气,我真心希望
在未来的日子不要在惹你生气了。怀孕这大半年的时间里,真的是辛苦你了,
是我有欠妥当,让你每次产检都跑那么远,甚是辛苦。可你也从来没有抱怨过,
太多太多你的好,我都记在心里,十年太短,一辈子太长,真心希望余生我们
能快快乐乐的生活下去。
没有珍贵的礼物,但是有一片真挚的心
望:
往后余生;
风雪是你,平淡是你;
清贫是你,荣华是你;
心底温柔是你;
目光所至也是你;
—–致我们的第一个七夕!