C++学习小结
分类: C/C++ 2012-06-03 15:57 1193人阅读 评论(2) 收藏 举报
c++deletestruct编译器classnull
一、构造和析构函数
C++在幕后为你写的的函数:一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符。另外,如果你没有声明任何构造函数,它也将为你声明一个缺省构造函数。所有这些函数都是公有的。换句话说,如果你这么写:
[cpp] view plaincopy
class Empty{};
和你这么写是一样的:
[cpp] view plaincopy
class Empty
{
public:
Empty(); // 缺省构造函数
Empty(const Empty& rhs); // 拷贝构造函数
~Empty(); // 析构函数 ---- 是否为虚函数看下文说明
Empty&
operator=(const Empty& rhs); // 赋值运算符
Empty* operator&(); // 取址运算符
const Empty* operator&() const;
};
深拷贝和浅拷贝:
默认拷贝构造函数均是浅拷贝。但是一个类可能拥有其它资源,如其构造函数分配了一个堆内存,析构函数释放了这个内存,则此时就需要进行深拷贝了,深拷贝不能依赖编译器实现。为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符。
拷贝构造函数的调用:
1、当用类的一个对象去初始化该类的另一个对象时。
2、当对象作为函数的实参传递给函数的形参时。
3、当函数的返回值是类的对象,函数执行完成返回时。
在构造函数中调用另一个构造函数,会生成一个临时对象,并且立即释放。 string c=a;只调用了拷贝构造函数。而string c; c=a;分别调用了构造函数和赋值函数。
构造函数和析构函数的注意点:
1、构造函数和析构函数不能有返回值
2、可以显式调用构造函数和析构函数
3、拷贝(复制)构造函数不能用值传递
4、不要在构造函数和析构函数中抛出异常和调用有异常抛出的函数,可能会有内存泄露!
5、确定基类有虚析构函数
二、static、const、友元与虚函数
1.静态成员使用static申明,在内存中永远只有一份实例(静态变量,类内声明,类外定义)
2.是类的对象所共有的
3.静态成员变量可以被成员函数访问,但静态成员函数只能访问静态成员变量
4.友元是为了一个普通函数直接访问一个类的保护甚至是私有成员的机制
虚函数:
在普通成员函数前面加 virtual 关键字
一个函数在基类申明一个virtual,那么在所有的派生类都是是virtual的 一个函数在基类为普通函数,在派生类定义为virtual的函数称为越位
抽象类:
具有纯虚函数的类就是抽象类
抽象类不能被实例化,所以抽象类只能以指针方式被应用
抽象类可以防止切片的发生
抽象类不产生虚表。
const对象与成员:
1.const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.
2.const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.
3.const成员函数不可以修改对象的数据,不管对象是否具有const性质。
4.然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,此时的const成员函数是可以修改它的
三、设计与实现
C++面向对象编程中一条重要的规则是:公有继承意味着 "是一个" 。一定要牢牢记住这条规则。
C++有两种多态多态形式:
1、编译时刻多态,编译时刻多态依靠函数重载或者模板实现
2、运行时刻多态。运行时刻多态依靠需函数虚接口实现
引用的使用原则:
1.在可以用引用的情况下,不要用指针
2.引用可以作为“左值”
3.引用不允许为空,当存在对象为空时,必须使用指针。 引用指向一个空值,是非常有害的!
4.尽量用“传引用”而不用“传值”
5.必须返回一个对象时不要试图返回一个引用
6.千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用
类中有const数据,必须要有构造函数对它初始化。
static const double a; //静态double常量声明!
const double 类名::a=1.04; //静态初始化!
T& operator[](int index); //传回数组的一个元素,可读,可写
const T& operator[](int index)const; //传回数组的一个元素,可读,不可写
重载函数,区分是不是重载函数的标准:
(1)只能靠函数的参数来区分重载函数(类型、个数、缺省参数)
(2)不能靠函数的返回值来区分重载函数
四、C++与C的一些区别
C中struct和C++中struct的区别:
C++的struct可以当作class来用,区别是,class中的成员默认是private,而struct的成员默认为public。
C中的struct只能是一些变量的集合体,可以封装数据却不可以隐藏数据,而且成员不可以是函数。
C中的Struct是用户自定义数据类型(UDT),C++中的Struct是抽象数据类型(ADT),支持成员函数的定义。
C++语言担保,如果p等于NULL,则delete p不作任何事情。
delete p 是一个两步的过程:调用析构函数,然后释放内存。
delete p调用的是operator delete(void*),而delete[] p调用的是operator delete[](void*)。
static 关键字至少有下列作用:
(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次, 因此其值在下次调用时仍维持上次的值;
(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
const 关键字至少有下列作用:
(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为 const,或二者同时指 定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。
一个基类及其继承类的实现:
[cpp] view plaincopy
class Base
{
public:
Base(const char *s=NULL);
Base(const Base& rth);
Base & operator=(const Base & oth);
virtual ~Base();
private:
char *m_data;
};
Base::Base(const char* s)
{
if(s==NULL)
{
m_data=new char[1];
m_data[0]='\0';
}
else
{
int length=strlen(s);
m_data=new char[length+1];
strcpy(m_data,s);
}
}
Base::Base(const Base & oth)
{
int len=strlen(oth.m_data);
m_data=new char[len+1];
strcpy(m_data,oth.m_data);
}
Base & Base::operator=(const Base & oth)
{
if(this==&oth) return *this;
delete []m_data;
int len=strlen(oth.m_data);
m_data=new char[len+1];
strcpy(m_data,oth.m_data);
return *this;
}
Base::~Base()
{
delete[] m_data;
}
class Derived : public Base
{
public:
Derived(const char* s=NULL,int a=0);
Derived(const Derived& oth);
Derived& operator=(const Derived& oth);
private:
int m;
};
Derived::Derived(const char* s,int a):Base(s),m(a){ }
Derived::Derived(const Derived& oth):Base(oth),m(oth.m){ }
Derived& Derived::operator=(const Derived& oth)
{
if(this==&oth) return *this;
Base::operator=(oth);
m=oth.m;
return *this;
}
C++编译器不支持模板头文件和实现代码分离的编译
在分离式编译的环境下,编译器编译某一个.cpp文件时并不知道另一个.cpp文件的存在,也不会去查找(当遇到未决符号时它会寄希望于连接器)。这种模式在
没有模板的情况下运行良好,但遇到模板时就不行,因为模板仅在需要的时候才会具现化出来,所以,当编译器只看到模板的声明时,它不能具现化该模板,只能创建一个具有外部连接的符号并期待连接器能够将符号的地址决议出来。然而当实现该模板的.cpp文件中没有用到模板的具现体时,编译器懒得去具现,所以,整个工程的.obj中就找不到一行模板具现体的二进制代码,于是连接器也傻了!
1 堆和栈那个是对程序员透明的?
答案:栈。
对程序员透明是指程序员不需要关心 举例来说 有些api函数对程序员透明 那么程序员只关心这个函数的功能 而不需要了解函数内部是如何实现的
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
2 请结合具体实例阐述一下面向对象中"多态"的概念。
答案:同一操作用于不同的类的实例,不同的类将进行不同的解释,最后产生不同的结果,它有两种: →编译时多态---- 通过overload来实现,系统在编译时,根据传递的参数和返回的类型等信息决定实现何种操作
→运行时多态---- 通过override来实现,根据运行时具体对象的类型决定调用哪个方法。
1. 问题:完全二叉树的结构
答案:深度为k,有n个节点的二叉树,当且仅当其每一个节点
都与深度 为k的满二叉树中编号从1至n的结点一一对应时,称之为完全
二叉树。
当初面试人员画了几个树让我辨认谁是完全二叉树。
3. 问题:什么是索引
答案:索引依附于基表,建立索引是加快查询的有效手段。
4. 问题:什么是视图 答案:视图是关系数据库系统提供给用户以多角度观察数据库中数据的重要机制。是从一个或多个基表(或视图)导出的表,它
与基本表不同,是虚表。
5. 问题:什么是游标
答案:游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果,每个游标区都有一个名字。用户可以通过游标逐一
获取记录,并赋给主变量,交由主语言进一步处理。
6. 问题:对数据库操作的语句
答案:select,insert,update,delete
7. 问题:数据库的操作过程
答案:(1)加载驱动程序;(2)建立数据库连接;(3)向数据库
发送SQL 语句;(4)事务处理;(5)管理连接。
8. 问题:所知道的排序方法的种类
答案:插入,快速,选择,交换,归并,基数,希尔等。
9. 问题:什么是MVC
答案:这个大家都清楚,可查询有关资料。 MVC本来是存在于Desktop程序中的,M是指数据模型,V是指用户界面,C则是控制器。使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据你可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。
模型-视图-控制器(MVC)
char *p;int i;p++与i++的区别?这个大家都知道就是p++是指向下一个元素,p的移动位置与p指针指向的类型有关,i++是自身增加一。差不多就是这样说的。
p保存占多少位? 我开始说与它指向的类型有关,然后她提示我说她不是那个意思,然后我说我感觉是在内存中占16位吧?我是这样说的,其实我也不清楚,c都忘了。
char *p=malloc(100),给p分配了多少个字节的空间?是堆内存还是栈内存?
我回答100个,(但是我忘了是堆还是栈)我认为是堆内存。
4。一个程序编译完成后在内存中是如何存储的??
我说这个没有学过,我把我认为的说了一下,她说她就是随便问问。
编译完,存储在硬盘上,obj文件。运行的时候才加载到内存中
5。java有多态性,继承,什么意思?是如何实现的?
(这个我虽然也知道大概 但是好像理解的也不是太深刻,说不太清晰)
答:我就说了前几天老师利用接口与DAOFactory实现的那个例子,她说那抽象类呢,我说不太上来但是也就我理解的说了点。我又扯上了重载,她就问重载是多态吗?我说不是(因为我记得不是),但是可以实现多态。说得很乱
class A{}
class B extends A{}
class C extends A{}
class D extends B{}
class E extends B{}
多态就是一个类型多个形态,它一般体现在类继承中;
上面的多态势这样体现的,A是所有类的父类,B、C继承了A,他们是A的多态,D、E同样,是B的多态,同时,因为D、E继承了B,B继承了A,所以D、E又是A的多态
数据抽象、继承和多态是面向对象程序设计语言的三大特性。多态,我觉得它的作用就是用来将接口和实现分离开,改善代码的组织结构,增强代码的可读性。在某些很简单的情况下,或许我们不使用多态也能开发出满足我们需要的程序,但大多数情况,如果没有多态,
就会觉得代码极其难以维护。
三层架构:是什么 ?
正确答案:(web服务器,数据库服务器,应
用程序服务器)
表现层:就是你提交到最终交互的产品,能够实物看到的。
逻辑层:说简单点就是你怎样把不同的数据层串联起来的代码存放的地方。
数据访问层:所有涉及到数据处理或访问的代码全部写在这一层
1、让我谈谈面向对象是怎样理解的? 对象就是一个名词,例如:猫
方法就是一个动作,例如:吃
属性就是属性,例如:颜色,名字
实例就是具体化,例如:
新建一个实例 我的猫=new 猫
定义 我的猫.颜色=黑色
定义 我的猫.名字=宝宝
调用 我的猫.吃(老鼠)
程序运行了 黑色宝宝吃老鼠
3、谈谈继承、多态、封装、抽象、重载、虚函数、抽象类。
重载verload;指使用同一个方法名,在调用时,编译器会根据方法参数列表的不同或是返回值类型的不同决定调用的方法。也就是说,同上个名称的方法能具备不同的功能。
比如:
functionGetSum(a:integer;b:integer):integer;overload; //求两个整数的和,返回值为整型;
functionGetSum(a:double;b:integer):double;overload; //求整数与实数的和,返回值为实数型;
functionGetSum(a:double;b:double):double;overload; //求实数的和,返回值为实数型;
虚函数是在基类中定义的,目的是不确定它的派生类的具体行为。例: 定义一个基类:class Animal//动物。它的函数为breathe()//呼吸。 再定义一个类class Fish//鱼 。它的函数也为breathe() 再定义一个类class Sheep //羊。它的函数也为breathe() 为了简化代码,将Fish,Sheep定义成基类Animal的派生类。
然而Fish与Sheep的breathe不一样,一个是在水中通过水来呼吸,一个是直接呼吸空气。所以基类不能确定该如何定义breathe,所以在基类中只定义了一个virtual breathe,它是一个空的虚函数。具本的函数在子类中分别定义。程序一般运行时,找到类,如果它有基
类,再找它的基类,最后运行的是基类中的函数,这时,它在基类中找到的是virtual标识的函数,它就会再回到子类中找同名函数。派生类也叫子类。基类也叫父类。这就是虚函数的产生,和类的多态性(breathe)的体现.
用一个简单的例子,比如说一个教师,我们把它作为一个抽象类,有自己的属性,比如说年龄,教育程度,教师编号等等,而教师也是分很多种类的,我们就可以继承教师类而扩展特有的种类属性,而普遍属性已经直接继承了下来。
而接口呢~还是拿教师做例子,教师的行为很多,除了和普通人相同的以外,还有职业相关的行为,比如改考卷,讲课等等,我们把这些行为定义成无body的方法,作为一个集合,它是一个interface。而教师张三李四的各自行为特点又有不同,那么他们就可以扩展自己的行为body。从这点意义上来说,interface偏重于行为。
总之,在许多情况下,接口确实可以代替抽象类,如果你不需要刻意表达属性上的继承的话。
1.final 怎么用?
答:final可以用在定义变量、方法以及类。
final的变量必须要初始化,也可以将初始化的操作推到类的静态块中进行,而且这样的变量不能再被重新赋值,可以将其看成这个类的“常量”了。
final的方法不能被所在的类的子类重写。
final的类不能再被继承了。
2.那么,finally怎么用?
答:finally适合try、catch块配合使用的。finally一般放一些收尾的代码,也就是说,不管try块中的代码是否正常执行,也不管catch块中的代码是否工作了,finally中的代码都要执行。比如,JDBC或是Hibernate中的关闭连接操作,就是放在finally中执行的。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
3.wait方法和sleep方法的区别?
答:他们都是用来堵塞、挂起当前线程的方法,大体上应该是wait方法可以释放原先占有的资源,而 sleep方法好像不能... 在以前的编写的代码中,我几乎没有用过控制线程的操作,这部分知识我确实不敢随便说。
两个人(A,B)都在(等待)看电影
A(sleep) 等待的时候不会把座位让给别人
B(wait) 也在等待但是它可以把座位让给别人自己站着
也就是说A等待的时候不给把资源交给别人..
而B等待的时候可以把资源交给别人...
1、在C#中,string str = null 与 string str = “” 请尽量使用文字或图象说明其中的区别。 回答要点:说明详细的空间分配。(10分) 答:string str = null 是不给他分配内存空间,而string str = "" 给它分配长度为空字符串的内存空间.
2、请详述在dotnet中类(class)与结构(struct)的异同:(10分) 答:Class可以被实例化,属于引用类型,是分配在内存的堆上的,Struct属于值类型,是分配在内存的栈上的.
4、分析以下代码,完成填空(10分)
string strTmp = "abcdefg某某某";
int i= System.Text.Encoding.Default.GetBytes(strTmp).Length; int j= strTmp.Length;
以上代码执行完后,i= j=
答:i=13,j=10
1.new有几种用法
第一种:new Class();
第二种:覆盖方法
public new XXXX(){}
第三种:new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。
值类型和引用类型的区别?写出C#的样例代码。
答:结构是值类型,类是引用类型,所以传结构就是值类型的应用啦,传对象或类就是引用类型的,这个不用多写了吧.
进程和线程分别怎么理解?
答:进程是老子,线程是儿子,没有老子就没有儿子,一个老子可以有多个儿子.一个儿子可以成为别人的儿子,一个老子也可以为别的老子生儿子.
如何在一个c++文件中包含一个c文件
extern "C"
在c++中,内联函数是怎么用的
内联函数就是在你写完程序后,在编译的时候,引用了内联函数的地方,编译器会将内联函数名换成内联函数体,以减少函数调用的时间消耗。一般情况下,用在函数体比较小,而调用特别频繁的情况下。就好比有一堆西瓜放在那里,普通的函数调用是谁要吃谁就去拿,而内联函数就是提前把西瓜分到了每个要的人的手里,这样就节约了去拿西瓜的时间了。 内联函数跟宏的意思差不多,就是在函数调用的地方,把函数调用语句改成函数体,比如: inline int fun(int a,int b)
{
return a+b;
}
main()
{
int a=1,b=2,c;
c=fun(a,b);
}
相当于
main()
{
int a=1,b=2,c;
c=a+b;
}
因为函数调用时,CPU要保存现场,要把参数入栈,要把返回值弹出,这是一个很复杂很消耗时间的过程,而内联函数相当于宏,不必处理保存现场,参数入栈等操作,所以速度比一般函数调用要快。
不过一般来说,内联函数要求不能带循环等复杂的结构,否则会被编译器做普通函数处理。 通常内联函数是为了提高函数调用的速度
Final和finally有什么区别
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 那final变量在哪儿初始化呢?
final变量初始化: 很多文章都这么说:其初始化可以在两个地方,一是其定义处,二是在构造函数中,两者只能选其一。胡说八道!final变量可以在任何可以被始化的地方被始化,但只能且必须被初始化一次.1)一旦被初始化后就不能再次赋值(重新指向其它对象),2)在任何引用之前或退出作用域时必须被初始化.
数据库中 视图的概念?是不是真实存在的?在物理空间上
视图:在SQL中,视图是外模式一级数据结构的基本单位。它是从一个或几个基本表中导出的 表,是从现有基本表中抽取若干子集组成用户的“专用表”。
基本表:基本表的定义指建立基本关系模式,而变更则是指对数据库中已存在的基本表进行删除与修改。
区别:1、视图是已经编译好的sql语句。而表不是
2、视图没有实际的物理记录。而表有。
3、表是内容,视图是窗口
4、表只用物理空间而视图不占用物理空间,视图只是逻辑概念的存在,表可以及时四对它进行修改,但视图只能有创建的语句来修改
5、表是内模式,试图是外模式
6、视图是查看数据表的一种方法,可以查询数据表中某些字段构成的数据,只是一些SQL语句的集合。从安全的角度说,视图可以不给用户接触数据表,从而不知道表结构。
7、表属于全局模式中的表,是实表;视图属于局部模式的表,是虚表。
8、视图的建立和删除只影响视图本身,不影响对应的基本表。
联系:视图(view)是在基本表之上建立的表,它的结构(即所定义的列)和内容(即所有数据行)都来自基本表,它依据基本表存在而存在。一个视图可以对应一个基本表,也可以对应多个基本表。视图是基本表的抽象和在逻辑意义上建立的新关系
游标是什么
游标字面理解就是游动的光标。
用数据库语言来描述:游标是映射在结果集中一行数据上的位置实体,有了游标,用户就可以访问结果集中的任意一行数据了,将游标放置到某行后,即可对该行数据进行操作,例如提取当前行的数据等。
DBMS的概念
数据库自带的的管理自身数据处理事务的工具
金屯镇中心小学开展校园环境卫生整治活动总结为进一步加强学校环境综合治理工作,推动创建文明校园活动的深入开展,维护学校及周边环境秩序…
这一周的C语言实训就要结束了,这一周我们实训的课题是蛇行数组,就是使一个n*n的二维数组按按蛇行走的样子一样从左上角排列到右下角,…
C++课程设计实训总结姓名:班级:学号:指导教师:一实训选题人事考勤系统二实训设计作品内容这次的课程设计,我们需要做一个人事考勤系…
常见异常:1、数据不在数据词典中的异常:产生原因:由于在创建实体类型时,没有将用到的实体序列化,导致在Config文件中找不到所要…
一、调用函数以及压栈:(1)、每个int占4个字节。(2)、通常栈是王内存低地址方向增长的,也就是说,先压栈的内容存放在高地址区域…
这一周的C语言实训就要结束了,这一周我们实训的课题是蛇行数组,就是使一个n*n的二维数组按按蛇行走的样子一样从左上角排列到右下角,…
金屯镇中心小学开展校园环境卫生整治活动总结为进一步加强学校环境综合治理工作,推动创建文明校园活动的深入开展,维护学校及周边环境秩序…
总体上必须清楚的:1)程序结构是三种:,三个循环结构),(if和switch)2)读程序都要从main()入口,然后从最上面顺序往…
赵锋20xx年x月x日C语言是目前大多数职业学校及大专院校开设的一门计算机基础课。对于刚接触计算机语言的职业学生,它具有较强的抽象…
这个星期,我们迎来了C语言实训——一次至为重要的实训。在这个星期里,同学们都很认真的做着那20多道实训题目,遇到不懂的互相请教,或…