标签:
答:Overload是重载的意思,Override是覆盖的意思,也就是重写。
(1)重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同),重载发生在同一个类中。
(2)重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。如果父类的方法是private类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。重写发生在不同的类(父类和子类)中。
(3)至于Overloaded的方法是否可以改变返回值的类型这个问题,要看你倒底想问什么呢?这个题目很模糊。如果几个Overloaded的方法的参数列表不一样,它们的返回者类型当然也可以不一样。但我估计你想问的问题是:如果两个方法的参数列表完全一样,是否可以让它们的返回值不同来实现重载Overload。这是不行的,我们可以用反证法来说明这个问题,因为我们有时候调用一个方法时也可以不定义返回结果变量,即不要关心其返回结果,例如,我们调用map.remove(key)方法时,虽然remove方法有返回值,但是我们通常都不会定义接收返回结果的变量,这时候假设该类中有两个名称和参数列表完全相同的方法,仅仅是返回类型不同,java就无法确定编程者倒底是想调用哪个方法了,因为它无法通过返回结果类型来判断。
a. 共享:多个应用程序可以使用同一个动态库,启动多个应用程序的时候,只需要将动态库加载到内存一次即可;
b. 开发模块好:要求设计者对功能划分的比较好。
缺点是不能解决引用计数等问题。
(2)静态库(Static Library):函数和数据被编译进一个二进制文件(通常扩展名为.LIB)。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其它模块组合起来创建最终的可执行文件(.EXE文件)。静态链接库作为代码的一部分,在编译时被链接。优缺点如下:
代码的装载速度快,因为编译时它只会把你需要的那部分链接进去,应用程序相对比较大。但是如果多个应用程序使用的话,会被装载多次,浪费内存。
数据库中的锁是网络数据库中的一个非常重要的概念,它主要用于多用户环境下保证数据库完整性和一致性。各种大型数据库所采用的锁的基本理论是一致的,但在具体实现上各有差别。目前,大多数数据库管理系统都或多或少具有自我调节、自我管理的功能,因此很多用户实际上不 清楚锁的理论和所用数据库中锁的具体实现。在数据库中加锁时,除了可以对不同的资源加锁,还可以使用不同程度的加锁方式,即锁有多种模式,SQL Server中锁模式包括:
1)共享锁
SQL Server中,共享锁用于所有的只读数据操作。共享锁是非独占的,允许多个并发事务读取其锁定的资源。默认情况下,数据被读取后,SQL Server立即释放共享锁。例如,执行查询“SELECT * FROM my_table”时,首先锁定第一页,读取之后,释放对第一页的锁定,然后锁定第二页。这样,就允许在读操作过程中,修改未被锁定的第一页。但是,事务 隔离级别连接选项设置和SELECT语句中的锁定设置都可以改变SQL Server的这种默认设置。例如,“ SELECT * FROM
my_table HOLDLOCK”就要求在整个查询过程中,保持对表的锁定,直到查询完成才释放锁定。
2)修改锁
修 改锁在修改操作的初始化阶段用来锁定可能要被修改的资源,这样可以避免使用共享锁造成的死锁现象。因为使用共享锁时,修改数据的操作分为两步,首先获得一 个共享锁,读取数据,然后将共享锁升级为独占锁,然后再执行修改操作。这样如果同时有两个或多个事务同时对一个事务申请了共享锁,在修改数据的时候,这些 事务都要将共享锁升级为独占锁。这时,这些事务都不会释放共享锁而是一直等待对方释放,这样就造成了死锁。如果一个数据在修改前直接申请修改锁,在数据修 改的时候再升级为独占锁,就可以避免死锁。修改锁与共享锁是兼容的,也就是说一个资源用共享锁锁定后,允许再用修改锁锁定。
3)独占锁
独占锁是为修改数据而保留的。它所锁定的资源,其他事务不能读取也不能修改。独占锁不能和其他锁兼容。
4)结构锁
结构锁分为结构修改锁(Sch-M)和结构稳定锁(Sch-S)。执行表定义语言操作时,SQL Server采用Sch-M锁,编译查询时,SQL Server采用Sch-S锁。
5)意向锁
意 向锁说明SQL Server有在资源的低层获得共享锁或独占锁的意向。例如,表级的共享意向锁说明事务意图将独占锁释放到表中的页或者行。意向锁又可以分为共享意向锁、 独占意向锁和共享式独占意向锁。共享意向锁说明事务意图在共享意向锁所锁定的低层资源上放置共享锁来读取数据。独占意向锁说明事务意图在共享意向锁所锁定 的低层资源上放置独占锁来修改数据。共享式独占锁说明事务允许其他事务使用共享锁来读取顶层资源,并意图在该资源低层上放置独占锁。
6)批量修改锁
批量复制数据时使用批量修改锁。可以通过表的TabLock提示或者使用系统存储过程sp_tableoption的“table lock on bulk load”选项设定批量修改锁。
char c = ‘\72‘; 中的\72代表一个字符,72是八进制数,代表ASCII码字符“:”。
10*a++ 中a先进行乘法运算再自增(笔试中经常喜欢出这类运算符优先级容易混淆的输出问题)。
double modf(double num, double *i); // 将num分解为整数部分*i和小数部分(返回值决定)
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int *p = &(a + 1)[3]; printf("%d\n", *p);
输出:5
char str1[] = "abc"; char str2[] = "abc"; const char str3[] = "abc"; const char str4[] = "abc"; const char *str5 = "abc"; const char *str6 = "abc"; char *str7 = "abc"; char *str8 = "abc"; cout << (str1 == str2) << endl; cout << (str3 == str4) << endl; cout << (str5 == str6) << endl; cout << (str7 == str8) << endl;
输出:0 0 1 1
char *str = "abc"; printf("%p\n", str1); cout << &str1 << endl;
上面打印的是字符串 “abc”的地址,下面打印的是 str1 变量的地址。
class CBook { public: const double m_price; CBook() :m_price(8.8) { } };
下面的做法是错误的:
class CBook { public: const double m_price; CBook() { m_price = 8.8; } };
而下面的做法虽未报错,但有个warning,也不推荐:
class CBook { public: const double m_price = 8.8; // 注意这里若没有const则编译出错 CBook() { } };
class CBook { public: mutable double m_price; // 如果不加就会出错 CBook(double price) :m_price(price) { } double getPrice() const; // 定义const方法 }; double CBook::getPrice() const { m_price = 9.8; return m_price; }
class CBook { public: CBook() { cout << "constructor is called.\n"; } ~CBook() { cout << "destructor is called.\n"; } }; void invoke(CBook book) { // 对象作为函数参数,如果这里加了个&就不是了,因为加了&后是引用方式传递,形参和实参指向同一块地 // 址,就不需要创建临时对象,也就不需要调用拷贝构造函数了 cout << "invoke is called.\n"; } int main() { CBook c; invoke(c); }
解答:注意拷贝构造函数在对象作为函数参数传递时被调用,注意是对象实例而不是对象引用。因此该题输出如下:
constructor is called. invoke is called. destructor is called. // 在invoke函数调用结束时还要释放拷贝构造函数创建的临时对象,因此这里还调用了个析构函数 destructor is called.
class CBook { public: double m_price; CBook() { CBook(8.8); } CBook(double price) : m_price(price) { } }; int main() { CBook c; cout << c.m_price << endl; // 此时并不会输出理想中的8.8 }
1.重载:重载从overload翻译过来,是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。
示例代码如下:
1
2
3
4
5
6
7
8
|
class
A{ public :
void
test( int
i);
void
test( double
i);
void
test( int
i, double j);
void
test( double
i, int j);
int
test( int
i); //错误,非重载 }; |
前四个互为重载函数,最后一个和第一个不是重载函数。
2.隐藏:隐藏是指派生类的函数屏蔽了与其同名的基类函数。注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。
实例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include<iostream>
using
namespace std;
class
A{ public :
void
fun1( int
i, int j){
cout <<
"A::fun1() : " << i <<
" " << j << endl;
}
}; class
B : public
A{ public :
//隐藏
void
fun1( double
i){
cout <<
"B::fun1() : " << i << endl;
}
}; int
main(){
B b;
b.fun1(5);
//调用B类中的函数
b.fun1(1, 2);
//出错,因为基类函数被隐藏
system ( "pause" );
return
0; } |
3.重写:重写翻译自override,也翻译成覆盖(更好一点),是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。
实例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#include<iostream>
using
namespace std;
class
A{ public :
virtual
void fun3( int
i){
cout <<
"A::fun3() : " << i << endl;
}
}; class
B : public
A{ public :
//重写
virtual
void fun3( double
i){
cout <<
"B::fun3() : " << i << endl;
}
}; int
main(){
A a;
B b;
A * pa = &a;
pa->fun3(3);
pa = &b;
pa->fun3(5);
system ( "pause" );
return
0; } |
上面为虚函数实现多态的代码,不明白的先看虚函数实现多态的原理。
重载和重写的区别:
(1)范围区别:重写和被重写的函数在不同的类中,重载和被重载的函数在同一类中。
(2)参数区别:重写与被重写的函数参数列表一定相同,重载和被重载的函数参数列表一定不同。
(3)virtual的区别:重写的基类必须要有virtual修饰,重载函数和被重载函数可以被virtual修饰,也可以没有。
隐藏和重写,重载的区别:
(1)与重载范围不同:隐藏函数和被隐藏函数在不同类中。
(2)参数的区别:隐藏函数和被隐藏函数参数列表可以相同,也可以不同,但函数名一定同;当参数不同时,无论基类中的函数是否被virtual修饰,基类函数都是被隐藏,而不是被重写。
调试运行如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#include<iostream>
using
namespace std;
class
A{ public :
void
fun1( int
i, int j){
cout <<
"A::fun1() : " << i <<
" " << j << endl;
}
void
fun2( int
i){
cout <<
"A::fun2() : " << i << endl;
}
virtual
void fun3( int
i){
cout <<
"A::fun3(int) : "
<< i << endl;
}
}; class
B : public
A{ public :
//隐藏
void
fun1( double
i){
cout <<
"B::fun1() : " << i << endl;
}
//重写
void
fun3( int
i){
cout <<
"B::fun3(int) : "
<< i << endl;
}
//隐藏
void
fun3( double
i){
cout <<
"B::fun3(double) : "
<< i << endl;
}
}; int
main(){
B b;
A * pa = &b;
B * pb = &b;
pa->fun3(3);
//重写,多态性,调用B的函数
b.fun3(10);
//隐藏,调用B的函数
pb->fun3(20);
//隐藏,调用B的函数
system ( "pause" );
return
0; } |
输出结果为:
1
2
3
4
|
B::fun3( int ) : 3
B::fun3( int ) : 10
B::fun3( int ) : 20
请按任意键继续. . . |
class CBook { public: static double m_price; }; double CBook::m_price = 8.8; // 只能在这初始化,不能在CBook的构造函数或直接初始化
标签:
原文地址:http://blog.csdn.net/feeltouch/article/details/45154799