转自:http://www.cnblogs.com/louistao/archive/2011/03/11/1981571.html
首先,引用一句Thinking in java中作者一直在强调的一句话:一切皆对象。
本文主要关于C++和JAVA类及一些其他关键概念的区别:
在OO编程中几个关键概念无非是类,封装,继承,多态。
一:关于类
(1):在C++中定义类:
class User
{
public:
Uers(string str,int yy){ name=str,age=yy;}
void print(){ ...... }
private
string name;
int age;
}; // 类的结尾处应该以“;”结束
在C++中有两种初始方式:
User u("zhangsan",20); //(A)
User *p=new User("zhangsan",20); //(B)
在A中,构造函数创建了变量u,它在堆栈上为新的对象分配内存。当u离开它的作用域的时候,它的内存自动释放。
在B中,操作符new在堆上为新的对象分配内存,并返回一个指向该块内存的指针,这块内存可由delete操作符显示的进行释放:delete p;(当我们在指向一个类类型的对象的指针上使用delete时,delete操作符将会调用这类的析构函数)。
在C++中,“.”和“->”操作符成为成员访问符:u.print();
p->print();
C++允许一个类的实现代码位于类的外部。需要使用作用域分解操作符“::” 帮助编译器确定这个定义是用于该类的。
在JAVA中定义类:
class User
{
private String name;
private int age;
public User(String str,int yy) {name = str,age = yy;}
public void print(){
System.out.println(.......);
}
}
初始化:User u=new User("zhangsan",20);
u.print();
下面做一些关于C++和JAVA在初始化方面总结:
在C++的第一种形式的初始化中,我们可以把u当作一个User的对象,这个构造函数的调用填充这块由u对象所占据的内存区区域。在第二种形式中,构造函数调用创建了一小块内存区域,其储存植为p(一个内存地址),然后填充一个较大的内存区域,赋值符右边所创建的User对象就存储在这个内存中。
在JAVA中,u值所保留的内存地址保存了User对象的对象引用。这个情况和C++的第二种情形差不多,只不过在JAVA中u不能像指针一样进行解引用。
(2):在C++中定义子类:
class StudentUser : public User
{
public:
studentUser(string nam,int y,string school):User(nam,y) { school=school}
void print(){
User::print();
cout<<"School:"<<school<<endl;
}
private:
string sclool;
};
一个派生类的构造函数在执行任何任务之前必须调用它的基类构造函数,如果派生类构造函数中并没有显示的调用基类的构造函数,系统将会试图调用基类的缺省构造函数。
在派生类中无法访问基类中的私有数据成员.在上述代码中
StudentUser *p=new StudentUser("zhangsan",20,"college")
将会打印: "zhangsan",20,School:college
前面两项是由基类中所定义的print()函数所打印。最后一项直接由子类的print()打印。对于StudentUser对象而言,它所看到的是在StudentUser类定义的print()。
这里关于函数的重载,覆盖,隐藏将在后面总结。
关于多态:
多态必须符合下面两个条件:
·对象必须通过指针或者引用进行操作
·基类中声明虚函数
在JAVA中定义子类
class StudentUser extends User{
private String school;
public StudentUser(String nam,int y,String sch)
{
super(nam,y);
school=sch;
}
public void print(){
super.print();
System.out.println(......)
}
}
在JAVA中super表达式调用了超类的构造函数。这一点与C++相似,我收藏了一篇文章,可做参考。
http://www.cnblogs.com/shootingstars/archive/2008/06/02/1211867.html
JAVA中的多态并不需要满足特别的条件,我们不需要向函数添加任何特殊的指示符使它们具有多态行为。
在JAVA中,我们把一个类的其中一些方法声明为final,从而实现有选择的控制继承的目的,当超类中的一个方法被声明为fianl 时,我们就无法在子类中对其进行覆盖 。C++并没有提供那样的关键字来防止类被扩展或者有选择的覆盖机制,但是C++中可以把基类中的构造函数放在类的私有部分,从而使它不被扩展。也就相当于该类不能被继承了。
在对象的销毁方面:C++当对象离开它的作用域之后,它的析构函数将会自动调用,从而销毁这个对象。析构函数可以缺省,在缺省的情况下,销毁就是简单的释放基本类型的数据成员所占的内存。如下:
#include<iostream>
using namespace std;
class X;
class Y
{
x *p;
public:
Y(X *q):p(new X(*q)){}
~Y(){ delete p;}
};
int main(){
X *px=new X();
Y y(px);
delete(px);
return 0;
}
这个例子中涉及到了为X类型的对象分配内存,因为Y数据成员p指向一个X类型对象。如果我们没有提供一个析构函数,那么系统将会默认的调用一个缺省的析构函数,缺省的析构函数将只释放数据成员P所占的4个字节内存,但P所指的内存并不会释放。
在JAVA中提供的是垃圾回收机制。
(3) 在JAVA中程序包机制获得在C++中可以通过名字空间机制来获得(namespace)。
(4) 访问控制:private能被友元访问,protected能被派生类访问
(5) 抽象类和接口:C++中一个类或者一个或多个成员函数被声明为纯虚函数,那么我们就无法创建该类对象。在JAVA中显式的使用abstract关键字声明。
虚函数是在函数名前加上virtual关键字,而纯虚函数与其叫纯虚函数还不如叫抽象类,它只是声明一个函数但不实现它,让派生类去实现它。例如:
virtual void print()=0;
(6) 对象的比较:C++重载操作符,或者利用某些函数,如string类中的compare(),JAVA中”==“和”equals()“。
(7) 类的静态成员:C++中静态成员对这个类的对象都是全局性的。在某处修改了将会影响所有的。在C++中可以通过类名和作用域分解操作符“::”直接访问一个公共静态数据成员,也可以通过成员访问