}
9.自己写一个程序,写str类的重载,add和delete还有“=”
#include
#include
classstr
{
public:
str(){}
str(char*source){
ch=newchar[strlen(source)+1];//初始化字符串数组
strcpy(ch,source);
(*(ch+strlen(source)+1))='\0';
}
friendstroperator+(str&c1,str&c2);//+号即add重载
friendstroperator-(str&c1,str&c2);//-号即delete重载
boolstroperator==(str&c1,str&c2);//==判等,重载两个字符串相等返回true,否则返回false
char*ch;
};
stroperator+(str&c1,str&c2){//把c2接到c1后
returnstr(strcat(c1.ch,c2.ch));
}
stroperator-(str&c1,str&c2){
return0;
}
booloperator==(str&c1,str&c2){
inti=0;
i=strcmp(c1.ch,c2.ch);//比较两个串
if(i==0)returntrue;//相等返回true
elsereturnfalse;//不等返回false
}
10.网络的三次握手,过程
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:
建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:
服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:
客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据
11.计算机操作系统同步的几种机制,特点
1)sleep与wakeup同步机制。
进程可由于多种原因使自己进入睡眠状态。
2)信号机制。
作为统一用户的诸进程之间通信的简单工具。
3)管道机制。
能够连接一个写进程和一个读进程,并允许他们从生产者-消费者方式进行通信的一个共享文件。
4)消息机制。
允许一个进程发送消息给其他进程。
5)共享存储区机制。
能使若干进程共享主存中的某个区域。
6)信号量集机制。
信号量集有若干个信号量,对这组信号量操作是原子性的。
12.STL的代码从广义上讲分为三类:
algorithm(算法)、container(容器)和iterator(迭代器),各自的作用和之间的关系
容器:
是一个保存其他对象的对象,可以存放任何类型的对象,是对数据结构的一种抽象,以类模板的方式实现而成的。
算法:
算法作用于容器。
算法定义了对容器容进行操作的方法,算法是对函数的一种抽象,采用函数模板实现。
迭代器是类似指针的对象,STL算法利用它们对存储在容器中的对象序列进行遍历。
迭代器提供了一种使容器与算法协同工作的机制。
一个容器可以生成一对迭代器来制定一个元素系列,而算法则是对该系列进行操作。
采用这种方式,容器和算法可以紧密地协作,同时还可以保持彼此“不知情”。
13.什么是多态?
如何实现多态,有几种方法?
多态是具有表现多种形态的能力的特征,在OO中是指,语言具有根据对象的类型以不同方式处理。
实现方法:
1)通过一个指向基类的指针调用虚成员函数的时候,运行时系统将能够根据指针所指向的实际对象调用恰当的成员函数实现
2)基于绝对位置的定位技术
两个实现方法具体看dev.yesky./189/2385189.shtml
三、选择题
选择题能想起来的就这些了,还有几题是多项题
1.chara=256;intb=a+1;cout<
答案为1
2.四个参数调用,传址,传值,引用,?
3.数组指针的几种表示,问哪一个不能表示那个地址?
4.宏定义,f(x)=x*x,接下去就忘记了,就自己看下宏定义吧
指针和引用之间存在三大区别:
1.不存在空引用;2.所有应用都要初始化;3.一个应用永远指向用来对它初始化的那个对象。
在类X的非常量成员函数中,this指针的类型为X*const。
也就是说它是指向非常量X的常量指针。
由于this指向的对象不是常量,因此它可以被修改。
而在类X的常量成员函数中,this的类型为constX*const,也就是说,是指向常量X的常量指针。
由于指向的对象是常量,因此不能修改。
赋值和初始化本质上是不同的操作。
对于int或double建类型来说,这些操作上的不同并不明显,因为在这种情况下,赋值和初始化不过都是简单的复制一些位而已。
然而对于用户自定义类型来说,情况截然不同。
赋值有点像一个析构动作后跟一个构造动作。
对于复杂得用户自定义类型来说,目标在采用源重新初始化之前必须被清除掉。
由于一个正当的赋值操作会清掉左边的参数,因此永远都不应该对一个初始化的存储区执行用户自定义赋值操作。
对于一个类X而言,复制构造函数应该被声明为X(constX&),而复制赋值操作则被声明为X&operator=(constX&)。
智能指针类型重载->和*操作符,来模仿指针的行为。
而函数对象类型则重载函数调用操作符()来创建类似于函数指针的东西。
函数对象就是常规的类对象,但是可以采用标准的函数调用语法来调用它的operator()成员。
回调函数(callback)与仿函数(functor)很多时候从用途上来看很相似,以致于我们经常将它们相提并论。
例如:
inlineboolcompare(inta,intb)
{
returna>b;
}
structcomparer{
booloperator()(inta,intb)const{
returna>b;
}
};
voidmain()
{
std:
:
vectorvec,vec2;
std:
:
sort(vec.begin(),vec.end(),compare);
std:
:
sort(vec2.begin(),vec2.end(),comparer());
}
仿函数(functor)之所以称为仿函数,是因为这是一种利用某些类对象支持operator()的特性,来达到模拟函数调用效果的技术。
如果这里vec,vec2这两个vector的容一样,那么从执行结果看,使用回调函数compare与使用仿函数comparer是一样的。
那么,我们应该用回调,还是用仿函数?
很多人都说用仿函数吧,回调函数是丑陋的,代码不太象C++风格。
但其实问题的本质不是在代码风格上,仿函数与回调函数各有利弊,不能一概而论。
仿函数(functor)的优点
我的建议是,如果可以用仿函数实现,那么你应该用仿函数,而不要用回调。
原因在于:
仿函数可以不带痕迹地传递上下文参数。
而回调技术通常使用一个额外的void*参数传递。
这也是多数人认为回调技术丑陋的原因。
更好的性能。
仿函数技术可以获得更好的性能,这点直观来讲比较难以理解。
你可能说,回调函数申明为inline了,怎么会性能比仿函数差?
我们这里来分析下。
我们假设某个函数func(例如上面的std:
:
sort)调用中传递了一个回调函数(如上面的compare),那么可以分为两种情况:
func是联函数,并且比较简单,func调用最终被展开了,那么其中对回调函数的调用也成为一普通函数调用(而不是通过函数指针的间接调用),并且如果这个回调函数如果简单,那么也可能同时被展开。
在这种情形下,回调函数与仿函数性能相同。
func是非联函数,或者比较复杂而无法展开(例如上面的std:
:
sort,我们知道它是快速排序,函数因为存在递归而无法展开)。
此时回调函数作为一个函数指针传入,其代码亦无法展开。
而仿函数则不同。
虽然func本身复杂不能展开,但是func函数中对仿函数的调用是编译器编译期间就可以确定并进行inline展开的。
因此在这种情形下,仿函数比之于回调函数,有着更好的性能。
并且,这种性能优势有时是一种无可比拟的优势(对于std:
:
sort就是如此,因为元素比较的次数非常巨大,是否可以进行联展开导致了一种雪崩效应)。
仿函数(functor)不能做的?
话又说回来了,仿函数并不能完全取代回调函数所有的应用场合。
例如,我在std:
:
AutoFreeAlloc中使用了回调函数,而不是仿函数,这是因为AutoFreeAlloc要容纳异质的析构函数,而不是只支持某一种类的析构。
这和模板(template)不能处理在同一个容器中支持异质类型,是一个道理。
函数对象的好处:
1.它重载了函数调用操作符,可以以普通函数调用的语法调用。
2.它派生于标准的binary_function基类,允许其他部分的STL实现询问函数对象编译期问题。
3.这个函数没有数据成员,没有虚函数,没有显示声明的构造函数和析构函数,且对operator()的实现是联的。
调用一个成员函数时涉及三个步骤:
1.编译器查找函数的名字。
2.从可用候选者中选择最佳匹配函数;
3.检查是否具有访问该匹配函数的权限。
访问修饰符可以用于表达和执行高级约束技术,指明一个类可以被怎样使用。
这些技术中最常见的一种是不接受对象的复制操纵,这是通过将其复制操作声明为private同时不为之提供定义而做到的。
构造函数被声明为受保护的,是为了允许派生类的构造函数使用它们,同时阻止创建独立的对象。
指明对象不应该被分配到堆上的方式之一,是将其对存分配定义为不合法,例如:
protected:
void*operatornew(size_t){return0;}当鼓励而非阻止使用堆分配时只需将析构函数声明为private即可。
当对象的名字离开其使用作用域时,任何一个声明自动或静态对象的尝试都将会导致一个隐式的析构函数调用。
Placementnew是函数operatornew的一个版本,它并不实际分配任何存储区,仅仅返回一个指向已经分配好空间的指针,所以不要对其进行delete操纵作。
但是确实创造了对象,避免使用delete操作符,代之以直接调用该对象的析构函数。
RAII表示资源获取即初始化,它利用C++对象生命期的概念来控制程序的资源。
如果希望保持对某个重要资源的跟踪,那么创建一个对象,并将资源的生命期和对象的生命期相关联。
所以得只能指针都重载->和*操作符,从而可以采用标准指针语法来使用它们。
还有一些职能指针(STL迭代器的指针)还重载了包括++,——,+,—以及[]等运算符。
职能指针通常采用类模板来实现,从而使它们可以指向不同类型的对象。
Auto_ptr是一个类模板,用于生成具体的职能指针,它们知道在用完之后如何清理资源。