c++与Java面向对象部分对比

为避免c++与Java面向对象知识混淆,特作此总结

2026-08-05 scanf ◷ 阅读约 5 分钟 c++ Java 面向对象 阅读 0

C++ 与 Java 面向对象部分对比


1. 类与对象的基本定义

特性 C++ Java
类关键字 class / struct classstruct 已退化为值类型容器)
对象创建 MyClass obj;(栈)或 new MyClass()(堆) 必须 new MyClass()(堆),无栈对象
析构/清理 析构函数 ~MyClass() finalize() 已废弃,用 AutoCloseable
内存管理 手动 delete 或智能指针 自动垃圾回收(GC)
// C++
class Dog {
public:
    Dog() { cout << "Dog created"; }
    ~Dog() { cout << "Dog destroyed"; }
};

Dog d1;            // 栈对象,自动析构
Dog* d2 = new Dog(); // 堆对象,需手动 delete
delete d2;
// Java
class Dog {
    public Dog() { System.out.println("Dog created"); }
    // 无析构函数,GC 负责回收
}

Dog d1 = new Dog();  // 唯一方式,引用在栈,对象在堆
// d1 离开作用域后,GC 不定期回收

2. 访问控制修饰符

修饰符 C++ Java
私有 private private
保护 protected(派生类和友元) protected(派生类 + 同包)
公共 public public
默认(包内) 无(struct 默认 public,class 默认 private) default(不写修饰符)
友元 friend 支持 无友元概念
// C++ 友元示例
class A {
private:
    int x;
    friend void show(A& a); // 全局函数可访问私有
};
void show(A& a) { cout << a.x; }
// Java 无友元,只能通过 getter/setter 或放宽访问权限
class A {
    private int x;
    public int getX() { return x; }
}

3. 继承与派生

特性 C++ Java
继承语法 class Derived : public Base class Derived extends Base
继承类型 public / protected / private public 继承(语义上的)
多继承 支持(多个基类) 不支持(单继承,但可通过接口多实现)
基类构造调用 初始化列表中显式调用 super() 自动/显式调用
重写(覆盖) virtual 函数 + override(C++11) 默认所有非静态方法可重写(除非 final
// C++ 多继承
class Base1 { public: void f1(); };
class Base2 { public: void f2(); };
class Derived : public Base1, public Base2 { };
// 需注意菱形继承问题(虚继承)
// Java 单继承,多实现
interface I1 { void f1(); }
interface I2 { void f2(); }
class Derived extends Base implements I1, I2 {
    public void f1() { ... }
    public void f2() { ... }
}

4. 多态与动态绑定

特性 C++ Java
实现多态 必须使用 virtual 关键字 默认所有非 static/final/private 方法都是多态的
虚函数表 有 vtable,需额外开销 也有类似机制,但由 JVM 管理
析构多态 基类析构函数必须为 virtual 无析构,但 close() 等需注意
调用方式 通过指针或引用调用虚函数 通过引用(都是指针语义)
// C++ 
class Base { public: virtual void speak() { cout << "Base"; } };
class Derived : public Base { public: void speak() override { cout << "Derived"; } };
Base* b = new Derived();
b->speak(); // 输出 "Derived"
delete b;   // 若析构非虚,则只调用 Base 析构
// Java 
class Base { public void speak() { System.out.println("Base"); } }
class Derived extends Base { public void speak() { System.out.println("Derived"); } }
Base b = new Derived();
b.speak(); // 输出 "Derived"
// 无需 delete,GC 自动处理

5. 抽象类与接口

特性 C++ Java
抽象类 含有纯虚函数的类 virtual void f()=0; abstract class
接口 纯抽象类(所有函数纯虚) interface 关键字(Java 8 后支持默认/静态方法)
多实现 多继承多个抽象类 一个类可实现多个接口
成员变量 抽象类可有任意成员变量 接口变量默认 public static final
构造器 抽象类有构造器 抽象类有构造器,接口无
// C++ 纯抽象类(模拟接口)
class Drawable {
public:
    virtual void draw() = 0;
    virtual ~Drawable() {} // 必须虚析构
};
class Circle : public Drawable {
public:
    void draw() override { cout << "Circle"; }
};
// Java 接口
interface Drawable {
    void draw(); // 默认 public abstract
    default void log() { System.out.println("log"); } // Java 8+
}
class Circle implements Drawable {
    public void draw() { System.out.println("Circle"); }
}

6. 构造与初始化

特性 C++ Java
构造器名称 与类同名,无返回值 与类同名,无返回值
默认构造 若未定义,编译器自动生成(需要时) 若未定义,编译器自动生成
初始化列表 支持(成员初始化列表) 不支持,用 super() 或实例初始化块
复制构造/赋值 有拷贝构造和拷贝赋值运算符 无(可用 clone() 或拷贝工厂)
静态初始化 全局/静态对象构造,static 初始化 static
实例初始化 构造体内 实例初始化块 { ... }
// C++ 初始化列表
class Point {
    int x, y;
public:
    Point(int a, int b) : x(a), y(b) { } // 必须用列表初始化 const/引用成员
};
// Java 实例初始化块
class Point {
    int x, y;
    { System.out.println("init block"); } // 每次构造前执行
    Point(int a, int b) { x = a; y = b; }
}
// 静态块
static { System.out.println("class loaded"); }

7. 向上转型与向下转型

特性 C++ Java
向上转型 隐式(派生类指针/引用 → 基类) 隐式(派生类引用 → 基类)
向下转型 dynamic_cast<Derived*>(basePtr)(需 RTTI) (Derived) baseRefinstanceof 检查
类型安全 dynamic_cast 失败返回 nullptr 转型失败抛出 ClassCastException
// C++ dynamic_cast
Base* b = new Derived();
Derived* d = dynamic_cast<Derived*>(b);
if (d) { /* 安全使用 */ }
// Java instanceof + 强转
Base b = new Derived();
if (b instanceof Derived) {
    Derived d = (Derived) b;
}

8. 静态成员与内部类

特性 C++ Java
静态成员变量 static int count;(需类外定义) static int count;(可直接初始化)
静态成员函数 static void f();(无 this 指针) static void f();(无 this 引用)
内部类(嵌套类) 嵌套类,可访问外部类的静态成员(若外部类对象指针则可访问非静态) 四种内部类:静态嵌套类、非静态内部类、局部内部类、匿名内部类
访问权限 嵌套类可声明为 private 内部类可声明为 private / protected / public
// C++ 静态成员需类外定义
class A { static int s; };
int A::s = 0;
// Java 静态内部类(类似 C++ 嵌套类)
class Outer {
    static class Inner { } // 可独立于外部实例存在
    class NonStaticInner { } // 持有外部类隐式引用
}

9. final / const / 不可变性

特性 C++ Java
常量成员 const 成员变量(构造列表初始化) final 成员变量(构造或直接赋值)
常量函数 成员函数后加 const(不修改对象) 无直接等价,但可通过 final 类或方法阻止重写
阻止重写 final(C++11)用于虚函数 final 修饰方法或类
阻止继承 final 修饰类(C++11) final 修饰类
// C++ const
class A {
    const int x;
public:
    A(int v) : x(v) { }
    void show() const { cout << x; } // 常成员函数
};
// Java final
class A {
    final int x;
    A(int v) { x = v; } // final 必须赋值
    // 无法声明 "不会修改成员" 的方法,但不可变类可设计
}

10. 对象生命周期与资源管理

特性 C++ Java
栈对象 自动构造/析构(RAII) 无栈对象,引用在栈,对象在堆
堆对象 new / delete(或智能指针) new,GC 自动回收
确定性销毁 是(析构函数确切时机) 否(GC 时机不确定)
资源释放(非内存) 析构函数中释放文件/锁等 需实现 AutoCloseable 并配合 try-with-resources
// C++ RAII
class File {
    FILE* f;
public:
    File(const char* name) { f = fopen(name, "r"); }
    ~File() { if (f) fclose(f); }
};
// Java try-with-resources
class File implements AutoCloseable {
    public void close() { /* 释放资源 */ }
}
try (File f = new File("data.txt")) {
    // 使用 f
} // 自动调用 close()

总结

特性 C++ Java
对象存储 栈或堆,灵活 全部在堆,引用在栈
析构 确定且可控 非确定,依赖 GC
多继承 支持 不支持,用接口代替
多态默认性 需显式 virtual 默认多态(非静态非 final)
访问控制粒度 类级 + 友元 类级 + 包级
类型转换安全 dynamic_cast 检查 instanceof 检查
资源管理 RAII 是王道 try-with-resources / 手动清理
常量性 const 强大(成员、函数、指针) final 仅修饰引用不可变,无常量成员函数

建议:将 Java 视为“C++ 的简化版 + 自动内存管理”,“没有析构函数、没有栈对象、没有多继承、没有友元、默认多态”。

Markdown 源文件

喜欢离线保存的话,可以把这篇文章下载为 Markdown 文件。

上一篇Python笔记(更新中...)
2026-07-11
下一篇论文格式规范
2026-08-22

相关文章