Java Language
C ++ Jämförelse
Sök…
Introduktion
Java och C ++ är liknande språk. Detta ämne fungerar som en snabbreferensguide för Java- och C ++ -ingenjörer.
Anmärkningar
Klasser definierade inom andra konstruktioner #
Definieras inom en annan klass
C ++
Nested Class [ref] (behöver en referens till slutande klass)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
[icke-statisk] Nested Class (alias Inner Class eller Members Class)
class OuterClass {
...
class InnerClass {
...
}
}
Statiskt definierade inom en annan klass
C ++
Static Nested Class
class Outer {
class Inner {
...
};
};
Java
Static Nested Class (alias Static Member Class) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
Definieras inom en metod
(t.ex. händelsehantering)
C ++
Lokal klass [ref]
void fun() {
class Test {
/* members of Test class */
};
}
Se även Lambda-uttryck
Java
Lokal klass [ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
Överbestyrning vs överbelastning
Följande åsidosättande vs överbelastningspunkter gäller både C ++ och Java:
- En åsidosatt metod har samma namn och argument som dess basmetod.
- En överbelastad metod har samma namn men olika argument och förlitar sig inte på arv.
- Två metoder med samma namn och argument men olika returtyp är olagliga. Se relaterade Stackoverflow-frågor om "överbelastning med annan returtyp i Java" - Fråga 1 ; fråga 2
polymorfism
Polymorfism är förmågan för objekt från olika klasser relaterade till arv att svara på samma sätt på samma metodsamtal. Här är ett exempel:
- basklass Form med område som en abstrakt metod
- två härledda klasser, Square och Circle, implementerar områdesmetoder
- Formhänvisning till torget och området åberopas
I C ++ aktiveras polymorfism med virtuella metoder. I Java är metoderna virtuella som standard.
Order för konstruktion / förstörelse
Objektrensning
I C ++ är det en bra idé att förklara en förstörare som virtuell för att säkerställa att underklassens förstörare kommer att kallas om pekaren i basklassen raderas.
I Java är en slutföringsmetod liknande en destruktor i C ++; finaliserare är emellertid oförutsägbara (de litar på GC). Bästa praxis - använd en "nära" metod för att uttryckligen rensa.
protected void close() {
try {
// do subclass cleanup
}
finally {
isClosed = true;
super.close();
}
}
protected void finalize() {
try {
if(!isClosed) close();
}
finally {
super.finalize();
}
}
Abstrakta metoder och klasser
Begrepp | C ++ | Java |
---|---|---|
Abstrakt metod deklarerats utan genomförande | ren virtuell metod virtual void eat(void) = 0; | abstrakt metod abstract void draw(); |
Abstrakt klass kan inte instanseras | kan inte instanseras; har minst en ren virtuell metod class AB {public: virtual void f() = 0;}; | kan inte instanseras; kan ha icke-abstrakta metoder abstract class GraphicObject {} |
Gränssnitt inga instansfält | inget "gränssnitt" nyckelord, men kan härma ett Java-gränssnitt med faciliteter i en abstrakt klass | väldigt lik abstrakt klass, men 1) stöder flera arv; 2) inga instansfält interface TestInterface {} |
Tillgänglighetsmodifierare
modifier | C ++ | Java |
---|---|---|
Allmänt - tillgängligt för alla | inga specialanmärkningar | inga specialanmärkningar |
Skyddad - tillgängligt med underklasser | också tillgängligt för vänner | också tillgängligt inom samma paket |
Privat - tillgängligt för medlemmar | också tillgängligt för vänner | inga specialanmärkningar |
standard | klassinställningen är privat; struct default är offentligt | tillgängligt för alla klasser inom samma paket |
Övrig | Friend - ett sätt att ge tillgång till privata och skyddade medlemmar utan arv (se nedan) |
C ++ vänsexempel
class Node {
private:
int key; Node *next;
// LinkedList::search() can access "key" & "next"
friend int LinkedList::search();
};
Det fruktade diamantproblemet
Diamantproblemet är en tvetydighet som uppstår när två klasser B och C ärver från A och klass D ärver från både B och C. Om det finns en metod i A som B och C har åsidosatt, och D inte åsidosätter det, då vilken version av metoden ärver D: den av B eller den av C? (från Wikipedia )
Även om C ++ alltid har varit mottagligt för diamantproblemet, var Java mottaglig tills Java 8. Ursprungligen stödde Java inte flera arv, men med tillkomsten av standardgränssnittsmetoder kan Java-klasser inte ärva "implementering" från mer än en klass .
java.lang.Object Class
I Java ärver alla klasser, antingen implicit eller uttryckligt, från Objekt-klassen. Alla Java-referenser kan kastas till Objekttypen.
C ++ har inte en jämförbar klass "Objekt".
Java-samlingar och C ++ -behållare
Java-samlingar är symonyma med C ++ Containers.
Java Collections Flowchart
C ++ Containers Flödesschema
Heltalstyper
bits | min | Max | C ++ Typ (på LLP64 eller LP64) | Java-typ |
---|---|---|---|---|
8 | -2 (8-1) = -128 | 2 (8-1) -1 = 127 | röding | bitgrupp |
8 | 0 | 2 (8) -1 = 255 | unsign char | - |
16 | -2 (16-1) = -32,768 | 2 (16-1) -1 = 32,767 | kort | kort |
16 | 0 (\ u0000) | 2 (16) -1 = 65,535 (\ uFFFF) | osignerad kort | röding (ej signerad) |
32 | -2 (32-1) = -2,147 miljarder | 2 (32-1) -1 = 2,147 miljarder | int | int |
32 | 0 | 2 (32) -1 = 4,295 miljarder | osignerad int | - |
64 | -2 (64-1) | 2 (16-1) -1 | lång* | lång lång |
64 | 0 | 2 (16) -1 | osignerad lång * osignerad lång länge | - |
*
Win64 API är bara 32 bitar
Statiska klassmedlemmar
Statiska medlemmar har klassomfång i motsats till objektomfång
C ++ Exempel
// define in header
class Singleton {
public:
static Singleton *getInstance();
private:
Singleton() {}
static Singleton *instance;
};
// initialize in .cpp
Singleton* Singleton::instance = 0;
Java- exempel
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
Klasser definierade inom andra konstruktioner
Definieras inom en annan klass
C ++
Nested Class [ref] (behöver en referens till slutande klass)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
[icke-statisk] Nested Class (alias Inner Class eller Members Class)
class OuterClass {
...
class InnerClass {
...
}
}
Statiskt definierade inom en annan klass
C ++
Static Nested Class
class Outer {
class Inner {
...
};
};
Java
Static Nested Class (alias Static Member Class) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
Definieras inom en metod
(t.ex. händelsehantering)
C ++
Lokal klass [ref]
void fun() {
class Test {
/* members of Test class */
};
}
Java
Lokal klass [ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
Pass-by-value & Pass-by-reference
Många hävdar att Java ENDAST är pass-by-value, men det är mer nyanserat än så. Jämför följande C ++ och Java-exempel för att se de många smakerna av pass-by-value (alias kopia) och pass-by-reference (alias).
C ++ Exempel (komplett kod)
// passes a COPY of the object
static void passByCopy(PassIt obj) {
obj.i = 22; // only a "local" change
}
// passes a pointer
static void passByPointer(PassIt* ptr) {
ptr->i = 33;
ptr = 0; // better to use nullptr instead if '0'
}
// passes an alias (aka reference)
static void passByAlias(PassIt& ref) {
ref.i = 44;
}
// This is an old-school way of doing it.
// Check out std::swap for the best way to do this
static void swap(PassIt** pptr1, PassIt** pptr2) {
PassIt* tmp = *pptr1;
*pptr1 = *pptr2;
*pptr2 = tmp;
}
Java-exempel (komplett kod)
// passes a copy of the variable
// NOTE: in java only primitives are pass-by-copy
public static void passByCopy(int copy) {
copy = 33; // only a "local" change
}
// No such thing as pointers in Java
/*
public static void passByPointer(PassIt *ptr) {
ptr->i = 33;
ptr = 0; // better to use nullptr instead if '0'
}
*/
// passes an alias (aka reference)
public static void passByAlias(PassIt ref) {
ref.i = 44;
}
// passes aliases (aka references),
// but need to do "manual", potentially expensive copies
public static void swap(PassIt ref1, PassIt ref2) {
PassIt tmp = new PassIt(ref1);
ref1.copy(ref2);
ref2.copy(tmp);
}
Arv kontra komposition
C ++ & Java är båda objektorienterade språk, så följande diagram gäller för båda.
Outcast Downcasting
Akta dig för att använda "downcasting" - Downcasting kastar ned arvhierarkin från en basklass till en underklass (dvs. motsatt av polymorfism). Använd i allmänhet polymorfism och åsidosättande istället för instans av & nedkastning.
C ++ Exempel
// explicit type case required
Child *pChild = (Child *) &parent;
Java-exempel
if(mySubClass instanceof SubClass) {
SubClass mySubClass = (SubClass)someBaseClass;
mySubClass.nonInheritedMethod();
}
Abstrakta metoder och klasser
Abstrakt metod
deklarerats utan genomförande
C ++
ren virtuell metod
virtual void eat(void) = 0;
Java
abstrakt metod
abstract void draw();
Abstrakt klass
kan inte instanseras
C ++
kan inte instanseras; har minst en ren virtuell metod
class AB {public: virtual void f() = 0;};
Java
kan inte instanseras; kan ha icke-abstrakta metoder
abstract class GraphicObject {}
Gränssnitt
inga instansfält
C ++
inget jämförbart med Java
Java
väldigt lik abstrakt klass, men 1) stöder flera arv; 2) inga instansfält
interface TestInterface {}