Ⅰ c++ stl里的向量vector非常好用,那么它是怎么实现的呢
这个要去翻源码了,STL里的代码说实话,真的看不太懂。
如果不是太纠结于具体细节,可以简单讲讲基本的实现思路,大致如下:
vector从功能上来讲,属于顺序存储容器,所以底层实现一般基于数组。
vector使用模板元编程技术实现,具体一点就是编译器根据使用时指定的实际类型在编译时执行模板特化,编译出对应的代码。也就是说vector<int> v1; vector<double>v2;它们各对应一个特化版本的代码。这提高了代码的抽象级别,但是对带来了代码膨胀的问题。
vector的重要特性之一就是实现了数组的动态递增。简单来说就是容器内部记录当前的足最大容量和使用量。当添加元素的时候,如果容器类发现当前的容量已耗尽,容器类会自动地重新分配一个更大容量的数组,把当前的所有元素过去,然后释放掉旧的数组,从而实现动态自增,这一切对使用者来说完全透明。
vector提供迭代器来提供统一的遍历访问接口,方便与STL中的其它组件进行交互。
这其中会有很多的细节,比如:
1. 是否允许vector在必要时缩小自身容量?
2. vector容量耗尽后的递增量是多少?
3. 是否应该提供线程安全容器?
有些东西可能真的需要去翻源码去看才能搞明白。或者可以参考侯捷的《STL源码剖析》。其实vector本身的实现并不会太复杂,它的实现思路也很简单,但是设计层面的一些取舍就需要经过仔细考量了。一般来说,STL是一个足够坚实的后盾,我们会频繁地使用它,以构建健壮高效的软件。能够理解STL里的一些设计思想和实现方式,对提高我们的编程思维和编程能力会所帮助。
Ⅱ 编写程序界面中包括一个标签、一个文本框和一个按钮。当用户单击按钮时,程序把文本框的内容复制到标签中
1、首先打开电脑的java编写工具,然后创建一个java项目,文件为Demo2。
Ⅲ 1、编程解决如下数学问题:有12升水,怎样利用一个8升和一个5升的容器将水分为两个6升打印出分水步骤。
#include"stdio.h"
void Move(int *a,int *b,int aMax,int bMax)
{
if(aMax>bMax)
{
if((*a+*b)>bMax)
{ *a=*a-(bMax-*b);
*b=*b+bMax-*b;
}
else
{
*b=*a+*b;
*a=*a-*a;
}
}
else
{
*b=*b+*a;
*a=0;
}
}
int check(int aMax,int bMax,int cMax)
{
if(aMax>bMax&bMax>cMax)
return 0;
else
return 1;
}
int main()
{
int a;
int b;
int c;
int aMax,bMax,cMax;
//aMax=40;bMax=14;cMax=8;
label3:
printf("待分配水量杯A:");
scanf("%d",&aMax);
printf("量杯B容量:");
scanf("%d",&bMax);
printf("量杯C容量:");
scanf("%d",&cMax);
if(check(aMax,bMax,cMax))
{
printf("容量输入有误!请重新输入.\n");
goto label3;
}
a=aMax;
b=0;
c=0;
int m=0;
while(m<100){
Move(&a,&b,aMax,bMax);
printf("A->B:%d %d %d\n",a,b,c);
m++;
if(b==aMax/2&a==aMax/2) goto label2;
Move(&b,&c,bMax,cMax);
printf("B->C:%d %d %d\n",a,b,c);
m++;
if(b==aMax/2&a==aMax/2) goto label2;
label1:
Move(&c,&a,cMax,aMax);
printf("C->A:%d %d %d\n",a,b,c);
m++;
if(b==aMax/2&a==aMax/2) goto label2;
Move(&b,&c,bMax,cMax);
printf("B->C:%d %d %d\n",a,b,c);
m++;
if(b==aMax/2&a==aMax/2) goto label2;
if(c==cMax) goto label1;
}
label2:
printf("共需%d步\n",m);
printf("%d %d %d\n",a,b,c);
return 0;
}
Ⅳ spring中的aop 是怎么面向切面编程的
Spring面向切面编程(AOP)
1 spring容器中bean特性
Spring容器的javabean对象默认是单例的。
通过在xml文件中,配置可以使用某些对象为多列。
Spring容器中的javabean对象默认是立即加载(立即实例化:spring加载完成,立即创建对象)
scope:属性
singleton:默认值为单例,默认也是立即加载,在加载完成spring容器的时候,bean对象已经创建完成
prototype:多例的,默认懒加载,spring容器加载完成的时候,不会创建bean的对象,只有从容器获得bean对象的时候,才进行bean对象的实例化
request: 将创建的javabean对象,封装到request范围
session:将创建的javabean对象,封装到session范围
Spring容器bean的对象生命周期:
Bean对象的创建一直到销毁为bean的生命周期。
生命周期的开始:
如果为单例,由加载完spring容器开始
如果为多例,由从容器获得bean对象开始
实例化
初始化
服务
销毁(单例:关闭容器的时候,多例由jvm自动回收)
2 spring的AOP面向切面编程
2.1 模拟银行转账业务
需求:实现银行的转账功能,在转账的时候需要完成
1 身份认证(登陆)
2 权限的验证
3 转账实现
4 历史交易记录,
分析:1,2,4三个功能对于银行的业务,属于公共的功能(共性的功能)
在功能实现的时候,需要将1,2,4抽取出来,单独实现,
做到了将共性的功能和核心的业务功能进行了分离
通过动态代理实现:共性的功能和核心业务功能的合并,产生核心业务对象的
在代码实现的时候,进行了功能实现的分离:
代码开发的进行分离,程序在运行的时候进行合并。
2.2 springAOP的思想
在系统开发中,将系统的共性的公共的功能独立实现,在程序运行的过程中,将共性功能和核心的业务功能,进行整合。
好处:
1 完成共性功能和核心业务功能的解耦合
2 提供共性功能的复用性。
2.3springAOP的概念
Aspect切面:封装共性功能的(增强功能的)类
Advice通过:切面类中封装的增强功能的方法。
PointCut:切入点,是一个集合的概念,该集合的表达使用一个正则表达式表达
所有核心业务对象的所有方法的前后(事务处理AOP典型的应用)
JoinPoint:连接点,程序中需要加入advice的地方,而且正在执行的ponitCut
织入(Weaving):将aspect和核心业务对象,进行整合的过程。
3 springAOP的实现
3.1通过特定接口实现
Aop通知的类型:
Before:前置通知
After:后置通知
Around:环绕通知
Throwing:异常通知
需求:实现在业务对象中的方法执行的时候,记录日志功能
3.1.1前置通知
packageorg.guangsoft.utils;
importjava.lang.reflect.Method;
importjava.util.Arrays;
importjava.util.Date;
importorg.springframework.aop.MethodBeforeAdvice;
/****
*前置增强:
*MethodBeforeAdvice接口表示重写的方法为前置advice
****/
{
@Override
publicvoidbefore(Methodmethod,
Object[]args,Objectobj)
throwsThrowable
{
System.out.println(method);
System.out.println(Arrays.toString(args));
System.out.println(obj);
System.out.println("BeforeLog-------------"+newDate());
}
}
AOP配置:
<?xmlversion="1.0"encoding="UTF-8"?>
<!--到入xml文件的约束-->
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
<!--实例化BeforeLog对象-->
<beanid="bf"class="org.guangsoft.utils.BeforeLog"></bean>
<!--实例化service对象-->
<beanid="us"class="org.guangsoft.service.impl.UsersServiceImpl"/>
<!--进行aop的配置,产生代理对象-->
<aop:config>
<!--声明切入点-->
<aop:pointcutexpression="execution(*org.guansoft.service.impl.*.*(..))"
id="pc"/>
<!--织入将通知和切入点进行合并(切面+核心业务对象)-->
<aop:advisoradvice-ref="bf"pointcut-ref="pc"/>
</aop:config>
</beans>
3.1.2后置通知
对业务对象的方法进行后增强。
packageorg.guangsoft.utils;
importjava.lang.reflect.Method;
importjava.util.Date;
importorg.springframework.aop.AfterReturningAdvice;
/***
*后置通知
****/
{
@Override
publicvoidafterReturning(Objectobj1,//obj1接收目标方法的返回值
Methodmethod,
Object[]args,
Objectobj2)throwsThrowable
{
//System.out.println(obj1+"----------------------"+obj2);
System.out.println("AfterLog-------------------"+newDate());
}
}
AOP配置:
<?xmlversion="1.0"encoding="UTF-8"?>
<!--到入xml文件的约束-->
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
<!--实例化BeforeLog对象-->
<beanid="bf"class="org.guangsoft.utils.BeforeLog"></bean>
<beanid="af"class="org.guangsoft.utils.AfterLog"></bean>
<!--实例化service对象-->
<beanid="us"class="org.guangsoft.service.impl.UsersServiceImpl"/>
<!--进行aop的配置,产生代理对象-->
<aop:config>
<!--声明切入点-->
<aop:pointcutexpression="execution(*org.guangsoft.service.impl.*.*(..))"
id="pc"/>
<!--织入将通知和切入点进行合并(切面+核心业务对象)-->
<aop:advisoradvice-ref="bf"pointcut-ref="pc"/>
<aop:advisoradvice-ref="af"pointcut-ref="pc"/>
</aop:config>
</beans>
3.1.3环绕通知
packageorg.guangsoft.utils;
importjava.lang.reflect.Method;
importjava.util.Arrays;
importjava.util.Date;
importorg.aopalliance.intercept.MethodInterceptor;
importorg.aopalliance.intercept.MethodInvocation;
/***
*环绕通知
****/
{
/**
*MethodInvocation中封装了目标对象,调用的方法,方法需要的参数
****/
@Override
publicObjectinvoke(MethodInvocationmi)throwsThrowable
{
Methodmethod=mi.getMethod();
Object[]args=mi.getArguments();
Objectobj=mi.getThis();
System.out.println(method);
System.out.println(Arrays.toString(args));
System.out.println(obj);
System.out.println("around------before--------"+newDate());
Objectrv=method.invoke(obj,args);//调用目标对象的方法,放行
System.out.println("around------after--------"+newDate());
returnrv;
}
}
AOP配置:同上
3.1.4 异常通知
packageorg.guangsoft.utils;
importjava.util.Date;
importorg.springframework.aop.ThrowsAdvice;
/****
*异常通知
***/
{
/***
*该类中的方法参考AfterReturningAdvice写
*该参数是用来接收异常信息的
****/
publicvoidafterThrowing(Throwableex)throwsThrowable
{
//System.out.println(obj1+"----------------------"+obj2);
System.out.println("ExceptionLog-----------"+ex.getMessage()
+"--------"+newDate());
}
}
Pointcut:核心业务对象
Advice:通知