|
演算子のオーバーロード
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
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_);
}
//2項演算子のオーバーロード
int operator+(const TEST &obj)
{
return(m_data_ + obj.m_data_);
}
int operator-(const TEST &obj)
{
return(m_data_ - obj.m_data_);
}
int operator*(const TEST &obj)
{
return(m_data_ * obj.m_data_);
}
int operator/(const TEST &obj)
{
return(m_data_ / obj.m_data_);
}
int operator%(const TEST &obj)
{
return(m_data_ % obj.m_data_);
}
bool operator==(TEST &obj)
{
return(this->m_data_ == obj.m_data_);
}
};
int main(int argc, char** argv)
{
int data = 0;
TEST obj1(2);
TEST obj2(3);
data = obj1 + obj2;
std::cout << "ope+ data = " << data << std::endl;
data = obj1 - obj2;
std::cout << "ope- data = " << data << std::endl;
data = obj1 * obj2;
std::cout << "ope* data = " << data << std::endl;
obj1.setData(10);
obj2.setData(5);
data = obj1 / obj2;
std::cout << "ope/ data = " << data << std::endl;
data = obj1 % obj2;
std::cout << "ope% data = " << data << std::endl;
if (obj1 == obj2)
{
std::cout << "m_data_の値は一緒です" << std::endl;
}
else
{
std::cout << "m_data_の値は等しくありません" << std::endl;
}
return(0);
}
添え字演算子のオーバーロード
添え字演算子をオーバーロードする事もできる。あるクラスを配列のように扱い、不正アクセスしないようにする事もできる。但し、オーバーヘッドがでかくなるので、お奨めではない。
添え字演算子の例
#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;
}
|