第三夜

学习源起:

昨晚的笔试题。

小公司,你懂得。

1,面向对象的几个基本特征,说说public、private、protected的意义和作用

封装、继承、多态

     封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

     继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

http://www.cnitblog.com/Lily/archive/2006/02/23/6860.aspx

          接口的多种不同的实现方式即为多态。http://baike.baidu.com/view/126521.htm

           protected与private基本相似,只有在继承时有较大的区别。继承的类可以访问protected成员,但是不能访问private成员。http://baike.baidu.com/view/833512.htm

------------------------------------反省线---------------------------------------------

真心觉得自己是个渣渣,老师说的那个“知道跟看到就能从脑子里拿出来用是不同的”真是精辟啊。

------------------------------------------------------------------------------------------------------------------------

2,请解释C++中的虚拟函数表。

我觉得自己得复习或者重新学习一下教材了,真心没印象,跟虚函数有关?

跟虚函数有关。

http://blog.csdn.net/haoel/article/details/1948051/

C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table

在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。

在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。

3,什么是override?什么是overload?

override覆盖,是指子类重新定义父类的虚函数的做法。

overload重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。http://www.cnitblog.com/Lily/archive/2006/02/23/6860.aspx

4,什么是值传递,什么是引用传递?

详见我的这个帖子,这个知识点后面还考了一次 http://bbs.csdn.net/topics/390470589
引用传递我就记住了一个关键字:别名。

5,如果是你来实现如下功能内存管理...

简化代码:
void GetMemory(char *p)
{
p=malloc();
}
void Test()
{
char *p;
GetMemory(p);
print(p);
}
这个主调函数没分配到内存,或者说子函数分配后又被释放掉了。跟值传递类似,子函数的改变不影响主函数。
char *GetMemory(char *p)
{
p="hello world";
return p;
}
void Test()
{
char *p;
p=GetMemory(p);
print(p);
}
我原以为返回的是个局部变量,调用结束后就会被释放掉,所以错误,但是哪里算是调用结束呢? GetMemory(p)还是p=GetMemory(p);这句执行完再释放?把p当成一个value就明白了,子函数p的地址传给了主函数的p,但p所指向的内存有么有被释放掉呢?
因为"hello world!"是一个字符串常量,存放在只读数据段该字符串常量所在内存不会被回收,故能够通过指针顺利无误的访问。http://blog.csdn.net/haiwil/article/details/6691854/

0.1 子函数调用结束后释放了什么?

学习源起:
之前有一个认识误区,以为局部变量都被释放掉了,结果malloc不会被释放掉。
“函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。”
想想也是,malloc是通过free释放掉的,由程序猿自己把握释放时机。所以下面的也是正确的,
char* GetMemory(char *p)
{
p=malloc();
retrun p;
}
void Test()
{
char *p;
GetMemory(p);
print(p);
}
另外,“ 局部变量也分局部自动变量和局部静态变量”,“ 可以返回指向局部静态变量的指针,因为静态变量的生存 期从定义起到程序结束”。也就是说局部静态变量也没被释放掉。所以这其实是个变量生存期的问题。下面详细学习一下生存期的知识。
综上,常量、malloc变量、静态变量在子函数调用后不会被释放掉。

0.2 C++变量类型

学习源起:

ppt文档 :4.5_

auto变量,用auto修饰的局部变量。缺省,即不加auto修饰的局部变量均视为自动变量。

寄存器变量:用register修饰的局部变量。不缺省。

ps:寄存器变量使用注意(5.31):

由于寄存器变量属于动态存储方式,故只有局部自动变量形式参数才可以定义为寄存器变量。

定义成寄存器类型的变量未必能按寄存器变量使用,寄存器不够时,还是当着一般变量来使用。


外部变量:用extern修饰的全局变量。缺省。且缺省初始化为0。(同static类似)。

ps:extern使用注意:

1,为避免多个文件extern同一个变量名但类型不匹配,尽量使用头文件extern所有需要extern的变量,然后引用该头文件,这称为声明的局部化。http://blog.csdn.net/youmengying/article/details/4468502

静态变量:1,内静态变量,用static修饰的局部变量;2,外静态变量,用static修饰的全局变量。

ps:外静态变量使用注意:

1,外静态变量虽然是全局变量,但作用域仅限于定义它的文件内,不可被extern,这是有static决定的。

0.3 数组名和指针

学习源起:
我原以为数组名和指针没什么区别,经常malloc出来一个指针p然后当数组名用来赋值p[i],但想想也知道肯定有时候不能混着写的。下面是一例:
“在一个源文件里定义了一个数组:char a[6];
在另外一个文件里用下列语句进行了声明:extern char *a;
  请问,这样可以吗? 
不可以,程序运行时会告诉你非法访问。原因在于,指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组,因此与实际的定义不同,从而造成运行时非法访问。应该将声明改为extern char a[ ]。”
我们可以推定,在其他涉及到声明与定义的时候也必须保持一致,即使他们使用起来没什么区别。
其他的例子可以参考下面的帖子:

6,读代码

源程序里有几个字符串函数不认识...........
strncpy:
char*strncpy(char*dest,char*src,size_t n);
参数 n 指定最多从 src 中拷贝 n 个字节到 dest 中,换句话说,如果拷贝到 '\0' 就结束,如果拷贝到 n 个字节还没有碰到 '\0' ,那么也结束.
strrchr:
extern char * strrchr (const char *s, int c)
查找在s字符串中最后一次出现字符c的位置。如果str中存在字符ch,返回出现ch的位置的指针;否则返回NULL。

7,以下代码是否有问题?

class KSth();
KSth & Do()
{
 KSth a;
...;
return a;
}
大家都知道一个常识:“千万不要返回局部对象或变量的引用和指针”。

额,我就是“大家”之外的一个人。

临时对象析构。
       返回局部对象的引用时,当函数 结束时,局部对象被析构,内存块的内容变为未定义内容,所以出错。

0.4 C++临时对象

"在C++语言中,临时变量的问题格外的重要,因为每个用户自定义类型的临时变量都要用户自定义的构造函数和析构函数(如果用户提供了)。"
"除了以类为参数以外,如果参数的类型是const T&类型,这也可能导致临时变量"

"还有一大类情况是临时变量的乐土,那就是表达式"

还有一种是格式转换时,无论是显式的还是隐式的转换。

  关于临时变量的生存期, "C++给出的规则是: 临时变量应该在导致临时变量创建的"完整表达式"求值过程的最后一个步骤被析构"

  但是"如果一个临时变量被绑定到一个引用,这个临时变量应该留到这个临时变量和这个引用那个先超出变量的作用域后才销毁"

对于临时变量,只能用常量的引用指向之”,涉及到赋值和传参,但本质都是格式转换与赋值。

short & b = i;错误,格式转换先产生个short临时变量然后将临时变量赋值,这里b必须是const。

为什么这样呢?很多人解释临时变量是const,并由此判定临时变量不能作为左值。

事实上,临时变量是可以被作为左值(LValue)并被赋值的”,“所以,临时变量不能作为非const引用参数,不是因为他是常量,而是因为c++编译器的一个关于语义的限制。

void uppercasify(const string& str) 
   
{} 
   
    
   
int main(int argc,char* argv[]) 
   
{ 
   
 char subtleBookPlug[] = "Effective C++"; 
   
    
   
 uppercasify(subtleBookPlug);  // 此处有类型转换 
   
    
   
 return 1; 
   
}


上面这段代码传参发生了类型转换,修改的只是一个临时变量而不是我们期望的 subtleBookPlug。


7,写出你看过的C++、windows、linux书籍的名字、作者名/译者名.

看书不看人的我只能说呵呵。






 
















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值