栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

OOP基本概念对比:RUST与CPP

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

OOP基本概念对比:RUST与CPP

对象封装

一般来说,一个对象,具有如下性质:

  • 一个区别于其他对象的名字
  • 若干个属性(数据,或字段)
  • 若干个行为(函数,或方法)

在C++中,使用public和private关键字来暴露或者保护对象内部的实现

//C++
#include 
#include 
using namespace std;
//类定义
class Person
{
public:
    Person(string&& name,int salary) : name(name), salary(salary) {};
public://公共字段
    string name;//公共属性
    void SayHi() { cout << name << ":hi" < cout << "sleep"; };//私有方法
};
int main()
{
    //在栈上创建对象
    Person bobFromStack("Bob",233);
    //在堆上创建对象
    auto pAliceFromheap = new Person("Alice",234);
    bobFromStack.SayHi();
    pAliceFromheap->SayHi();
    system("pause");
    return 0;
}

在Rust中,所有名字默认是private的,只能在当前文件中访问,如果要将名字暴露给外部,需要使用pub关键字

路径用于引用模块树中的项 - Rust 程序设计语言 中文版 (rustwiki.org)

//Rust
pub struct Person {//导出结构体名
  pub name:String,//可供其他模块访问的公共字段
  salary:i32,//仅能在本文件中访问的私有字段
}

impl Person {//为结构体实现方法
  pub fn SayHi(&self) {//可供其他模块访问的公共方法
      println!("{}:Hi",self.name);
  }
  fn Sleep(&self){//仅能在本文件中访问的私有方法
    println!("Sleep");
  }
}

fn main() {
  //在栈上创建对象
  let bobFromStack = Person{name: String::from("Bob"),salary:233,};
  //在堆上创建对象
  let aliceFromHeap = Box::new(Person{name: String::from("Alice"),salary:234,});
  bobFromStack.SayHi();
  aliceFromHeap.SayHi();
}
继承
//C++
class Worker: public Person {
  public:
    string company;
};
//RUST没有继承,使用组合而非继承来复用代码

// https://rustwiki.org/zh-CN/book/ch17-01-what-is-oo.html


多态 C++函数重载

重载是指不同参数的静态函数可以使用相同的函数名

int Add(int i1, int i2)
{
    return i1 + i2;
}
int Add(int i1, int i2, int i3)
{
    return i1 + i2 + i3;
}
C++虚函数重写

重写是指子类重新实现了父类中的虚函数

class Base{
//使用virtual关键字定义虚函数
virtual void fun(int a){cout<<"1"<
//重写父类中的虚函数
void fun(int a){cout<<"2"< 
C++非虚函数重定义 

重定义是指子类重新实现了父类中的非虚函数

class Base{

//非虚函数fun
 void fun(int a){cout<<"1"< 
RUST为类型实现Trait 

Trait抽象了类的接口,只要是实现了对应Trait的任意类型,都将拥有接口所描述的特性,类比C++中的某些概念,Trait中的方法可以被沿用(类似于继承)或者重新实现(类似于重定义)

另外,如果在Trait中只提供声明不提供实现,那么实现该Trait的类型必须提供该声明的定义(类似于必须将纯虚函数实例化)

RUST不提供重载,如果要支持不同参数的同名函数,考虑使用泛型、tuple、Trait之间的互相配合

trait:定义共享的行为 - Rust 程序设计语言 中文版 (rustwiki.org)

pub struct Person {//导出结构体名
  pub name:String,//可供其他模块访问的公共字段
  salary:i32,//仅能在本文件中访问的私有字段
}

impl Person {//为结构体实现方法
  pub fn SayHi(&self) {//可供其他模块访问的公共方法
      println!("{}:Hi",self.name);
  }
  fn Sleep(&self){//仅能在本文件中访问的私有方法
    println!("Sleep");
  }
}

struct Robot{
  name:String,
}

pub trait SayHello {
  //提供了默认实现的的行为
  fn sayHello(&self){
    println!("Default Hello")
  }
  //未提供默认实现的行为,必须实现该行为才能使用本特征
  fn mustSaySometing(&self);
}

impl SayHello for Person{
  //sayHello覆盖默认行为
  fn sayHello(&self){
    println!("{}:Hello",self.name)
  }
  //实现mustSaySometing
  fn mustSaySometing(&self){println!("Wtf?")} 
}

impl SayHello for Robot{
  //sayHello沿用默认行为
  //实现mustSaySometing
  fn mustSaySometing(&self){println!("Calm down!")} 
}

fn main() {
  
  let bob = Person{name: String::from("Bob"),salary:233,};
  let alice = Robot{name: String::from("alice"),};
  
  bob.sayHello();//Bob:Hello
  alice.sayHello();//Default Hello
  
  bob.mustSaySometing();//Wtf?
  alice.mustSaySometing();//Calm down!
}
统一接口调用

在C++中,如果想调用多个对象的某个同名方法,不需要针对每个对象都写一次调用,利用虚函数即可

#include 
#include 
#include 

using namespace std;

class Person
{
public:
    Person(string&& name,int salary) : name(name), salary(salary) {};
public:
    string name;
    virtual void SayHi() { cout << name << ":hi" < cout << "sleep"; };
};

class Worker :public Person
{
public:
    Worker(string&& name, int salary,string&& company) :Person(move(name),salary),company(company) {};
public:
    string company;
    void SayHi() { cout << company << " " << name << ":hi" << endl; };
};

int main()
{
    vector vec;
    auto bob = new Person("Bob",233);
    auto alice = new Worker("Alice", 233, "Bili");
    vec.push_back(bob);
    vec.push_back(alice);
    for (auto& item:vec)
    {//当父类指针指向子类对象时,针对虚函数会分别调用子类中的方法
        item->SayHi();
    }
    system("pause");
    return 0;
}

而在RUST中,想要统一调用某个特定名字的方法,需要用到Trait Object的概念

为使用不同类型的值而设计的 trait 对象 - Rust 程序设计语言 中文版 (rustwiki.org)

特征对象 - Rust语言圣经(Rust Course)

pub struct Person {//导出结构体名
  pub name:String,//可供其他模块访问的公共字段
  salary:i32,//仅能在本文件中访问的私有字段
}

impl Person {//为结构体实现方法
  pub fn SayHi(&self) {//可供其他模块访问的公共方法
      println!("{}:Hi",self.name);
  }
  fn Sleep(&self){//仅能在本文件中访问的私有方法
    println!("Sleep");
  }
}

struct Robot{
  name:String,
}

pub trait SayHello {
  //提供了默认实现的的行为
  fn sayHello(&self){
    println!("Default Hello")
  }
  //未提供默认实现的行为,必须实现该行为才能使用本特征
  fn mustSaySometing(&self);
}

impl SayHello for Person{
  //sayHello覆盖默认行为
  fn sayHello(&self){
    println!("{}:Hello",self.name)
  }
  //实现mustSaySometing
  fn mustSaySometing(&self){println!("Wtf?")} 
}

impl SayHello for Robot{
  //sayHello沿用默认行为
  //实现mustSaySometing
  fn mustSaySometing(&self){println!("Calm down!")} 
}

fn main() {
  let bob = Person{name: String::from("Bob"),salary:233,};
  let alice = Robot{name: String::from("alice"),};
 //使用Trait Object来存储实现了相同Trait的不同类型
  let items:Vec> = vec![
    Box::new(Person{name: String::from("Bob"),salary:235,}),
    Box::new(Robot{name: String::from("alice"),}),
  ];
 //调用不同类型中的同一个方法
  for item in items {
      item.mustSaySometing();
  }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/893331.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号