Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

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が出力される
}

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away