以下是用 **C++** 和 **C#** 实现的两个简单示例,展示它们在 **语法、内存管理、面向对象** 和 **运行时特性** 上的核心区别。
---
### **示例 1:内存管理与指针**
#### **C++ 示例:手动内存管理**
```cpp
#include
class Person {
public:
std::string name;
Person(const std::string& n) : name(n) {
std::cout << "Constructor called for " << name << std::endl;
}
~Person() {
std::cout << "Destructor called for " << name << std::endl;
}
};
int main() {
// 动态分配内存(手动管理)
Person* p = new Person("Alice");
std::cout << "Name: " << p->name << std::endl;
delete p; // 手动释放内存
return 0;
}
```
**输出:**
```
Constructor called for Alice
Name: Alice
Destructor called for Alice
```
**关键点:**
- 使用 `new` 动态分配内存,必须显式调用 `delete` 释放。
- 直接通过指针访问对象属性(`->`)。
- 析构函数(`~Person`)在 `delete` 时自动调用。
---
#### **C# 示例:自动垃圾回收**
```csharp
using System;
class Person {
public string Name { get; set; }
public Person(string n) {
Name = n;
Console.WriteLine($"Constructor called for {Name}");
}
~Person() {
Console.WriteLine($"Finalizer called for {Name}");
}
}
class Program {
static void Main() {
// 创建对象(无需手动释放)
Person p = new Person("Alice");
Console.WriteLine($"Name: {p.Name}");
// 对象超出作用域后,GC(垃圾回收器)自动回收内存
}
}
```
**输出(可能延迟显示析构函数):**
```
Constructor called for Alice
Name: Alice
Finalizer called for Alice
```
**关键点:**
- 使用 `new` 创建对象,无需手动释放。
- 属性(`Name`)通过 `get/set` 封装,语法更简洁。
- 析构函数(`~Person`)由垃圾回收器(GC)在对象不可达时自动调用,时间不确定。
---
### **示例 2:面向对象与语法**
#### **C++ 示例:多重继承与模板**
```cpp
#include
class Base1 {
public:
virtual void foo() { std::cout << "Base1::foo" << std::endl; }
};
class Base2 {
public:
virtual void bar() { std::cout << "Base2::bar" << std::endl; }
};
// 多重继承
class Derived : public Base1, public Base2 {
public:
void foo() override { std::cout << "Derived::foo" << std::endl; }
void bar() override { std::cout << "Derived::bar" << std::endl; }
};
int main() {
Derived d;
d.foo(); // 调用 Derived::foo
d.bar(); // 调用 Derived::bar
return 0;
}
```
**关键点:**
- 支持 **多重继承**(一个类继承多个基类)。
- 使用 `override` 显式覆盖虚函数。
- 模板(未展示)可实现泛型编程。
---
#### **C# 示例:接口与属性**
```csharp
using System;
interface IAnimal {
string Name { get; }
void Speak();
}
class Dog : IAnimal {
public string Name { get; private set; }
public Dog(string name) {
Name = name;
}
public void Speak() {
Console.WriteLine($"{Name} says: Woof!");
}
}
class Program {
static void Main() {
IAnimal dog = new Dog("Buddy");
Console.WriteLine($"Animal Name: {dog.Name}");
dog.Speak();
}
}
```
**输出:**
```
Animal Name: Buddy
Buddy says: Woof!
```
**关键点:**
- 使用 **接口**(`IAnimal`)实现多态,替代多重继承。
- 属性(`Name`)自动封装(`get`/`set`)。
- 接口方法(`Speak`)需显式实现。
---
### **代码对比总结**
| **特性** | **C++** | **C#** |
|------------------------|----------------------------------------|---------------------------------------|
| **内存管理** | 手动(`new`/`delete`) | 自动(垃圾回收器) |
| **指针** | 支持(直接操作内存) | 默认不支持(可通过 `unsafe` 启用) |
| **面向对象** | 多重继承、虚函数、模板 | 接口、属性、泛型 |
| **语法** | 复杂(需声明头文件、作用域解析符 `::`)| 简洁(属性、自动封装) |
| **运行时环境** | 直接编译为机器码 | 依赖 .NET 运行时(JIT 编译) |
| **典型用途** | 系统级开发(游戏引擎、驱动) | 应用级开发(Web、桌面、企业级应用) |
---
### **如何选择?**
- **C++**:需要 **极致性能** 或直接操作硬件(如游戏引擎、嵌入式系统)。
- **C#**:追求 **开发效率** 和 **安全性**(如企业软件、Unity 游戏、Web 应用)。
通过代码对比,可以直观看到两者在 **控制权**(C++)与 **易用性**(C#)上的权衡。
评论区: