前言:
多种语言同时使用时,总是会出现不适应的情况,所以标记一下他们的差异,方便参考。
正文:
(1)创建和销毁对象:
差异:C++中的“A a;”在栈中创建了对象,可直接使用,Java中的这种形式则不会创建对象。
C++:
- A a; //对象占用栈空间,可以直接使用,生命周期为所在作用域,不需要手动销毁。
- B* b = new B(); //对象占用堆空间,可以直接使用,生命周期无限,需要手动“delete b;”。
Java:
- A a; //对象没有生成,不可直接使用,访问其内部成员时会报空指针异常,只可以作为左值。
- B b = new B(); //对象占用堆空间,可以直接使用,生命周期无限,不再使用时需要手动置“b =
null;”,当再无标识符指向堆中该对象时,系统GC会适时回收其占用的堆内空间。
(2)构造函数-互调:
差异:C++的构造函数不能像Java随意调用另一个构造函数。
Java:
很常用的写法,“this(参数);”即可。
C++:
如果像Java的写法会得不到预期的结果。原因是在第二次调用构造函数时,会生成一个匿名的本类对象,参数会作用于这个匿名对象的内部,匿名对象的生命周期也仅限于第一个构造对象的花括号内,随着第一个构造函数执行结束,匿名对象也会被销毁,并带走了要设置的参数,参数也就不会作用于第一个对象了。
实现Java的构造函数互调的效果,仨方案(建议第一、二种,为啥?写的懂,读的也懂呗):
- 使用默认参数,一个带默认参数的构造函数就可以实现Java两个构造函数的效果,这也可能是C++不推荐像Java那么玩的主要原因吧;
- 将构造函数公共部分提出来,写成私有函数;
- 使用new运算符的方式:
A()
{
new (this)A(0);
}
(3)析构函数-基类的虚析构函数:
差异:C++的基类中的析构函数需要写成虚函数。
C++:
“~A()”,就是构造函数前面加一个小波浪。
其实在这里提了析构函数只是想说一个事,基类的析构函数必须写成虚函数“virtual ~A() {}”,原因网上有很多介绍很好的,不多叙述。
Java:
无析构函数,Java不需要手动释放内存,这也是Java为什么老少皆宜,Java也可以写服务器程序,虽然运行慢点,但是不至于出大事啊。
(4)头文件:
差异:C++的头文件干什么用的呢?
C++:
(1)引用开关
#ifndef _A_H
#define _A_H
代码
#endif
(2)函数和变量声明使用了其他类,使用“class B;”声明即可,在cpp文件中再“#include “B.h”;”。
(3)定义作用域。
Java:
无需声明,直接定义即可。
(5)C++的内联函数:
差异:C++的内联函数可以减少函数调用,节省开销。Java无此写法。
C++:
inline int max(int a, int b)
{
return a > b ? a : b;
}
注意:
(1)编译器隐式地将在类内定义的成员函数当做内联函数(就是声明和定义在一块的成员函数);
(2)建议将内联函数写在头文件中,这样可以确保每个调用该内联函数所使用的定义都是相同的,并可以使编译器准确地找到其定义。
Java:
无此写法。
(6)C++的初始化列表:
差异:C++的初始化列表可以提高效率,能用就尽量用,Java无此写法。
C++:
class A
{
A(string str) : mStr(str) {};
string mStr;
};
构造函数执行分两个阶段:初始化阶段和赋值阶段。
必须使用初始化列表的情况:
(1)常量初始化,原因:常量只可以初始化一次。
(2)引用的初始化,原因:引用不可以赋值,只可以初始化。(这里要说一下,即使引用可以作为左值,也是改变的初始化时指向对象的值,并不是改变的其指向);
(3)无默认构造函数的类对象的赋值。原因:对象的赋值,需要调用其默认无参构造函数和赋值运算符,需要两步。但如果写过初始化列表中,则只会走它的拷贝构造函数,一步就完成。
(4)派生类在初始化列表中调用基类的构造函数。
Java:
无此写法。
(7)常量定义:
C++:
#define CHILD_AGE 10 //结尾不要有分号
const int CHILD_AGE = 10;
二者有些区别,前者作用于预处理阶段,简单替换,替换后边界错误,能导致出现不可预期结果;后者在编译阶段,是有类型的。
Java:
static final int CHILD_AGE = 10;
(8)单例模式:
差异:C++和Java根据各自语言特性,代码的写法上有些不同,但思想一致。
详见:设计模式-单例模式
(待完成)C++的默认参数:
C++:
Java:
(待完成)C++的引用:
C++:
Java:
(待完成)C++的指针:
C++:
Java:
(待完成)C++的命名空间:
C++:
Java:
(待完成)volatile:
差异:C++的volatile和Java的完全不一样。如果想达到Java的volatile功能,可以使用atomic。
C++:直接处理硬件的程序通常会有这样的数据成员,它们的值由程序本身之外的动因控制,这样的值可能会被编译器优化的不可预期,这时就需要用volatile修饰该变量,禁止编译器优化该成员。
写法:volatile int i;
详见:https://blog.csdn.net/fxy0325/article/details/89856871
Java:线程之间同步
(待完成)抽象类:
(待完成)抽象方法 或 虚函数:
C++:
C++中叫做虚函数,可以有函数体。
Java:
Java中叫做抽象方法,不可以有方法体,所在类叫做抽象类,不可以实例化,必须由需要实例化的子类实现方法体(强制性的,和Interface一样),抽象类中有定义实现的方法(Java1.8新特性中Interface中也可以有已实现的方法了),因为在抽象类中的已实现方法中可以调用抽象方法,所以我们在抽象类的有方法体的方法中定义共通的功能,将抽象方法设计为子类间区别的功能。