LoginSignup
9
5

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-03-09

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など)を比べてみたいですね。

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5