![]() |
![]() |
TOP > C++ > 演算子のオーバーロード |
![]() |
![]() |
演算子のオーバーロード
C++では、演算子をオーバーロードする事ができる。
オペレータをオーバーロードするには、operatorキーワードを使って演算子を定義する。
void operator+(...);
単項演算子のオーバーロード
単項演算子のオーバーロードは、単項演算子の右辺にあるオブジェクトが引数として渡される。
例えば、obj1 = obj2;
という式がある時、「=」をオーバーロードした時は、
obj1.=(obj2);の意味となる。
(注意)後置型インクリメント・デクリメントは、引数にint型をとるようにする。(実際には受け取らないが、ダミーで宣言する)
単項演算子のオーバーロードの例
#include <iostream> class TEST { private: int m_data_; public: TEST(int data) :m_data_(data) { }; ~TEST(){}; //データのセット void setData(int data) { m_data_ = data; } int print() { return(m_data_); } //単項演算子のオーバーロード TEST& operator=(const TEST &obj) { m_data_ = obj.m_data_; return(*this); } void operator++(int) { m_data_++; return; } void operator--() { --m_data_; return; } TEST* operator->() { return(this); } }; int main(int argc, char** argv) { TEST obj1(2); TEST obj2(3); obj1 = obj2; std::cout << "ope= m_data_ = " << obj1.print() << std::endl; obj1++; std::cout << "ope= m_data_ = " << obj1.print() << std::endl; --obj1; std::cout << "ope= m_data_ = " << obj1.print() << std::endl; std::cout << "ope= m_data_ = " << obj1->print() << std::endl; return(0); } 2項演算子のオーバーロード
2項演算子のオーバーロードは、演算子の右辺が引数として渡され、左辺のオブジェクトのオーバーロードした演算子が呼び出される。
例えば、data = obj1 + obj2;の時は、
data = obj1.+(obj2);
とこんな感じになる。
2項演算子のオーバーロードの例
#include 添え字演算子のオーバーロード
添え字演算子をオーバーロードする事もできる。あるクラスを配列のように扱い、不正アクセスしないようにする事もできる。但し、オーバーヘッドがでかくなるので、お奨めではない。
添え字演算子の例
#include <iostream> class TEST { private: int m_cur_data_; int *m_data_; unsigned int m_max_size_; public: TEST(unsigned int size) : m_cur_data_(0), m_data_(0), m_max_size_(size) { if (m_max_size_ > 0) { m_data_ = new int[m_max_size_]; } }; TEST(const TEST& obj) : m_cur_data_(0), m_data_(0), m_max_size_(0) { } ~TEST() { if (m_data_ != NULL) { delete[] m_data_; } }; void operator=(int data) { std::cout << "=" << std::endl; m_cur_data_ = data; } TEST& operator[](unsigned int suffix) { std::cout << "[]" << std::endl; if (suffix < 0 || suffix > m_max_size_) { std::cout << "不正メモリへのアクセスです" << std::endl; } else { std::cout << "要素[" << suffix << "]にデータ" << m_cur_data_ << "を格納しました" << std::endl; m_data_[suffix] = m_cur_data_; } return(*this); } int& operator[] (unsigned int suffix) { return (m_data_[suffix]); } }; int main(int argc, char** argv) { TEST obj(10); obj[1] = 3; return(0); } new・delete演算子のオーバーロード
new・delete演算子もオーバーロードできる。メモリ確保や開放のデバッグに有効
メンバ関数にする際は、静的メンバ関数にしなければならない。
グローバル関数にする際は、以下の書式となる。
void* operator new(size_t size){}
void* operator new[](size_t size){}
void operator delete(void* po){}
void operator delete[](void* po){}
new/delete演算子のオーバーロードの例
#include <iostream> void* operator new(size_t size) { std::cout << " alloc size = " << size << std::endl; return(malloc(size)); } void* operator new[](size_t size) { std::cout << " alloc size = " << size << std::endl; return(malloc(size)); } void operator delete(void* po) { std::cout << "delete address = " << std::hex << po << std::endl; } void operator delete[](void* po) { std::cout << "delete address = " << std::hex << po << std::endl; } int main(int argc, char** argv) { int *p_value1 = (int *)new int; int *p_value2 = (int *)new int[10]; delete p_value1; delete[] p_value2; } |
![]() |
![]() |
Copyright 2007 ためになるホームページ All Rights Reserved. |