C++
Rust

C++のclassとRustのstruct/implとを比較


C++とRustとの実装比較

Rustにはクラスがないのですが、継承等を考えなければstructとimplで同じことができそうなので、試しに実装を比較してみました。


C++ ver.

適当なクラスMyStructを作ってmain.cppから叩くだけ。また、結果を標準出力に書き出しますが、そのためにoperator<<を作っておきます。

ちなみに、名前空間mystructをわざわざ使ってるのもRustとの比較のためです。


メイン部分 (C++)


main.cpp

#include "mystruct.h"

#include <iostream>
#include <string>

using mystruct::MyStruct;
using std::string;

int main() {
const string name("hoge");
constexpr unsigned char age = 8;
MyStruct m(name, age);
std::cout << "Hello, " << m << std::endl;
}



MyStructのヘッダー (C++)

インクルードガードやnamespaceを入れると少しゴタゴタした感じの見た目になってしまいますね。


mystruct.h

#ifndef _MYSTRUCT_H_

#define _MYSTRUCT_H_
#include <iostream>
#include <string>

namespace mystruct {

class MyStruct {
public:
MyStruct() = delete;
MyStruct(const std::string &, const unsigned char);

friend std::ostream &operator<<(std::ostream &, const MyStruct &);

private:
const std::string name;
const unsigned char age;
};
} // namespace mystruct

#endif



MyStructの実装 (C++)

operator<<の実装がダサい・・・。


mistrust.cpp

#include "mystruct.h"


namespace mystruct {
using std::ostream;
using std::string;

MyStruct::MyStruct(const string &name, const unsigned char age)
: name(name), age(age){};

ostream &operator<<(ostream &os, const MyStruct &m) {
os << "(" << m.name << ", " << static_cast<unsigned int>(m.age) << ")";
return os;
}

} // namespace mystruct



コンパイルと実行 (C++)

$ c++ -std=c++14 -Wall -Wextra main.cpp mystruct.cpp -o a.out 

$ ./aout
Hello, (hoge, 8)

コードはこちら


Rustのコード

cargoでプロジェクト作成して試してましたが、ここでは関連する最小限だけを抜き出してみます。


メイン部分 (Rust)


main.rs

mod mystruct;

use mystruct::MyStruct;

fn main() {
let name = String::from("hoge");
let age = 8;
let m = MyStruct::new(&name, age);
println!("Hello, {}", m);
}



MyStructの実装 (Rust)


mystruct.rs

use std::fmt;

pub struct MyStruct {
name: String,
age: u8,
}

impl fmt::Display for MyStruct {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.name, self.age)
}
}

impl MyStruct {
pub fn new(name: &String, age: u8) -> MyStruct {
MyStruct {
name: name.clone(),
age,
}
}
}



コンパイルと実行 (Rust)

比較のため、cargoの代わりに直接rustcを使っておきます。

$ rustic main.rs

$ ./a.out
Hello, (hoge, 8)

コンパイルのコマンド短い・・・。

Rustのコードはこちら


雑感

この例だと、Rustの手厚い言語仕様のサポートのおかげでとても楽に書けますね。コードが小さすぎてC++のお作法部分のゴタゴタが目立ってるだけかもしれませんが。

やっぱり比較できる程度に慣れてくると楽しいですね。今度はスマートポインターに相当する機能(BoxやらRcなど)を比べてみたいですね。