c++类和java类的一些区别

对象成员初始化:

两者的区别,有些比较老的书上介绍,c++不允许在类声明中初始化.

但是c++11已经允许在类声明中进行初始化了

接下来讨论c++相对特殊的,const变量和static变量以及引用的初始化.

考虑下面几种变量如何初始化的问题

#include <iostream>
class Test{
	int a;
	const int b;
	static int c;
	const static int d;
	int & e;
public:
	Test():b(2){
		
	}
};

首先,a的初始化是你想怎么初始化都行,比如在类声明中直接赋值,int a=0;或者在构造函数括号里面赋值,或者在初始化列表中赋值.反正不管你想怎么弄他都可以.第二个的初始化就有点限制,可以通过初始化列表或者直接在声明中赋值,但不能够在构造函数括号里面赋值,因为该变量是const型,意味着进入括号之前,该变量就已经固定了,所以在括号里面不能修改其值.再说第三个,第三个是个static变量,所以,其实不存在在构造函数中初始化它的问题,因为他根本不属于某个固定的对象,只是你可以在其中修改他的值.那么再说到他的初始化问题,由于他属于static,所以初始化列表行不通,由于不是const所以直接在声明中写也不行,唯一的办法就是在原型文件中单独写.至于第四个和第三个的区别就是多了const,所以他较三多了在声明中初始化的方法.再说到第五个,第五个是引用,其实可以看做是第二个相似,因为引用的本质是常量指针,所以他也只能和第二个一样,可以用初始化列表或者直接在声明中赋值.

传参方式:

首先两者的声明就不一样

在java中,创建一个类对象,一般是需要new一个东西出来,这是因为他使用一个对象的本质是指针类似.而在c++中,则只需要声明一下,就创建了一个类,如果在c++中用new,则是需要用类的指针接收.

这也就是说,如果我们在函数中用参数传递类,那么,c++是不能对类本身进行修改,而是对类的拷贝.而java则不同,他是传的指针,可以直接修改.

如果追究到底的话其实不存在传参方式的问题,两者传参方式都一样,只不过java中的变量一般都是引用或者叫做指针,而c++中的变量就是变量.

作用域:

作用域,前面说过,两者创建类的方法一般不同,用正常方法创建出来的c++类,他是个普通变量,所以,如果我们在另一个类A中有这样的成员变量类B,则在类A是不能够访问类B的私有成员C的,即,使用选择操作符B.C是不行的,因为C++默认是private,而java中用默认的声明方法,我们是可以在类A中通过类B去访问类B的成员变量的,只要他们在一个包中,这样的话的确方便了许多.而结果也是失去了一定的封闭性.还有一点就是内部类的问题,c++中不可以用外部类去操作内部类的变量,内部类也不能操作外部类的变量,两个类没有逻辑上的关系,只有声明域的关系,而java不同,它正好都可以,因为内部使用了一种静态方法的机制.

函数重载:

c++中,同名的函数,派生类享有支配权,即,会优先调用派生类的同名函数,但是父类的函数也可以通过  变量.父类::函数名  显式调用.也就是说并不会被覆盖,只是优先权的问题,而在java中,则不可以通过上面这种方法调用,但java可以在子类中新建一个不同名的函数,然后在这个函数中调用super中的函数,这样就可以避免父类的函数在子类中不可访问的问题.

静态成员的继承:

被声明为private的变量和函数都不可继承,这点在java和c++中是一样的,java更简单些,他的继承没有分为三类,但c++中需要注意的一点区别是,静态成员只要不是被声明为private的则在派生类中都可以访问,而不管声明的继承方式是private还是public.

另外补充一点,非const 的static变量在c++中仍旧不能在类声明中初始化.

 

多态性:

java中的多态实现方式有两种,一种是通过继承父类,然后重写父类中的同名函数,一种是通过实现接口中的函数,这两种方式都差不多,类似于给对象提供一个向外的接口,让外部可以调用.c++中的多态实现方式是通过虚函数来实现,通过声明基类中的方法为虚函数,然后用一个父类的指针或引用来达到在运行时根据不同的类调用不同的方法.c++中的虚函数,不管在派生类中的访问权限是什么,只要是通过虚函数接口调用,都是可以调用的(当然父类中的虚函数必须是public).

由于上面的内容需要详细展开,所以我在下面贴上代码.
 

#include <iostream>
using namespace std;
class Base
{
public:
	virtual void who()
	{
		cout << "base" << endl;
	}
};
class first_d :public Base
{
private :
	void who()
	{
		cout << "first derivation\n" << endl;
	}
};
class second_d :public first_d
{
private :
	void who()
	{
		cout << "second derivation\n" << endl;
	}
};
int main()
{
	Base* base;
	first_d fd;
	second_d sd;
	base = &fd;
	base->who();
	base = &sd;
	base->who();
	getchar();

	first_d* pfd;
	pfd = &fd;
	pfd->who();//error
        pfd = &sd;
        pfd->who();//error
	return 0;
}

这里有三个层次,首先最底层的base他的函数who是public的,所以用这个指针调用两个派生类fd和sd中的who函数是允许的,不用管在派生类中的访问权限是什么,相当于父类接口是允许访问的,然后通过这个接口去动态绑定子类的函数.

通过first_d类型的指针是不可以访问其who函数,同样也不可以访问派生类对象sd的who函数,因为在要求访问这个接口时候就被禁止了,所以不存在后面动态绑定的情况,即使在sd中将who函数声明为public也是一样.

 

另外,java中,子类同名函数覆盖父类的同名函数之后,在类外是不可以访问到父类被覆盖的同名函数的(但是可以通过新建一个函数然后super调用),而c++则可以通过加上父类名称显式调用.

 

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值