LoginSignup
7
6

More than 5 years have passed since last update.

RubyのクラスをC++で考えてみた。

Last updated at Posted at 2015-11-01

Rubyのクラスを勉強するため、C++と比較しながら考えてみました。
あくまでC++erがRubyを理解をしやすくするためのイメージという感じです。


クラス宣言

どちらも似たようなもん。
Ruby

class.rb
class Foo
end

C++

class.cpp
class Foo
{
};

初期化

RubyはinitializeメソッドがC++のコンストラクタに相当するもの。(オブジェクトの生成時に自動的に呼び出される)
ちなみにC++のデストラクタに相当するものはRubyにはない。(やろうと思えばできるみたい)

Ruby

class.rb
class Foo
  def initialize
    #初期化処理
  end
end

C++

class.cpp
class Foo
{
  Foo();
};

//コンストラクタ
Foo::Foo()
{
  //初期化処理
}

継承

どちらも似たようなもん。
ただしRubyは多重継承ができない。(できない方がいいかもだけど)
厳密には異なるが、似たような機能としてMix-inがある。

Ruby

class.rb
class SuperFoo 
end

class Foo < SuperFoo
end

C++

class.cpp
class SuperFoo
{
};

class Foo : SuperFoo
{
};

オーバーライド

どちらも似たようなもん。

Ruby

class.rb
class SuperFoo 
  def method
  end
end

class Foo < SuperFoo
  def method
  end
end

C++

class.cpp
class SuperFoo
{
   virtual void method();
};

void SuperFoo::method()
{
}

class Foo : SuperFoo
{
  void method() override; 
};

void Foo::method()
{
}

継承元のメソッドを使いたい時

継承元のメソッドをオーバーライドしたメソッド内で使いたい場合、
Rubyはsuperと記述するだけで継承元のメソッドを呼び出すことが可能。

Ruby

class.rb
class Foo < SuperFoo
 def method
     super;
 end
end

C++

class.cpp
void Foo::method()
{
   SuperFoo::method();
};

引数のあるメソッドのオーバーライド

引数のあるメソッドの場合でも、superと書くだけでオーバーライドしたメソッドの引数を
継承元のメソッドに引数として渡してくれる。

class.rb
class SuperFoo
  def method(str)
  end
end

class Foo < SuperFoo
  def method(str)
    super
  end
end

引数を渡したくない時

初期値を使いたい等で引数を渡したくない場合、空の()を入れることで引数を渡さなくなる。

class.rb
class SuperFoo
  def method(str = "Foo")
  end
end

class Foo < SuperFoo
  def method()
    super()
  end
end

クラス変数

C++だとこの機能に似たようなものが存在しない?(知らないだけかも)
機能を簡単に説明すると、同じクラスのオブジェクトで共通して使え、スコープはクラス内のみという変数。
C++では静的変数をクラス内で宣言することで似たような処理を行える。(2015/11/2 追記)

class.rb
class Foo
  @@count = 0

  def initialize
    @@count += 1
  end

  def count
    return @@count
  end
end

foo1 = Foo.new
p foo1.count  #1が出力される

foo2 = Foo.new
p foo2.count  #2が出力される

p foo1.count  #2が出力される
cpp/class.cpp
class Foo {
public:
    Foo();
    static int getInstanceCount(){ return count; };
private:
    static int count;
};

int Foo::count = 0;

Foo::Foo(){
    count += 1;
}

int main() {
    std::cout << Foo::getInstanceCount() << endl; //0が出力される

    Foo f1;
    std::cout << Foo::getInstanceCount() << endl; //1が出力される

    Foo f2;
    std::cout << Foo::getInstanceCount() << endl; //2が出力される

    return 0;
}

インスタンス変数・インスタンスメソッド

Rubyでは変数名の先頭に@を付けた変数がインスタンス変数となる。

Ruby

class.rb
class Foo 
 def initialize
   @count = 0 #インスタンス変数
 end

 def print #インスタンスメソッド
   puts count
 end

end

C++

class.cpp
class Foo()
{
   Foo();
   void print();

private:
   int m_count;//インスタンス変数(メンバ変数)
};

Foo::Foo() :m_count(0)
{
}

void Foo::print() //インスタンスメソッド
{
   std::cout<< m_count << endl;
}

クラスメソッド

C++でいえば静的関数に相当するもの。

Ruby

class.rb
class Foo 
 def Foo.power2( num ) #クラスメソッド
   return num*num
 end
end

p Foo.power2( 10 ) #インスタンス無しで呼び出せる 100が出力される

C++

class.cpp
class Foo()
{
   static double power2( const int num ){ return num*num; };
};

main()
{
   std::cout<< Foo::power2( 10 ) << endl;  //インスタンス無しで呼び出せる 100が出力される
}

7
6
5

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
7
6