User Tools

Site Tools


programming:cpp:class

自作クラス

クラスを自作する必要がある際に考えること

unordered_map などの key に使う際には 'operator==' と hash 関数のオーバーロードが,
ordered なコンテナの key に使う際には'operator<' のオーバーロードが必要

例えば int と double をもつクラスをキーとして使う場合は,

MyClass.hpp
#ifndef MYCLASS_HPP
#define MYCLASS_HPP
 
#include <cstddef>
 
#include <boost/functional/hash.hpp>
 
class MyClass {
public : 
  int var1;
  double var2;
 
  bool operator==(const MyClass &rhs) const;
  bool operator<(const MyClass &rhs) const;
 
  friend std::size_t hash_value(const MyClass &obj) {
    std::size_t h = 0;
    boost::hash_combine(h, obj.var1);
    boost::hash_combine(h, obj.var2);
    return h;
  }
 
};
 
#endif
MyClass.cpp
#include "MyClass.hpp"
 
bool MyClass::operator==(const MYClass &rhs) const {
  return var1 == rhs.var1 && var2 == rhs.var2;
}
 
bool MyClass::operator<(const MyClass &rhs) const {
  if ( var1 != rhs.var1 )
    return var1 < rhs.var1;
  return var2 < rhs.var2
}

また,デバッグなどでクラスの中身を見たい場合に出力ストリームをオーバーロードしておくと便利.
自分は使わなかったが,入力ストリームをオーバーロードすれば,テキストファイルから一括で入力することも可能になる気がする.
実際に使ってみたらできた.
入出力ストリームの例は以下の通り.

MyClass.hpp
#ifndef MYCLASS_HPP
#define MYCLASS_HPP
 
#include <iostream>
 
class MyClass {
public : 
  int var1;
  double var2;
 
  friend std::ostream &operator<<(std::ostream &os, const MyClass &obj);
  friend std::istream &operator>>(std::istream &is, MyClass &obj);
 
};
MyClass.cpp
#include "MyClass.hpp"
 
#include <iostream>
 
std::ostream &operator<<(std::ostream &os, const MyClass &obj) {
  os << "Integer value : " << obj.var1 << "\n"
     << "Double value : " << obj.var2 << "\n";
 
  return os;
}
 
std::istream &operator>>(std::istream &is, MyClass &obj) {
  is >> obj.var1 >> obj.var2;
  return is;
}

operator== を定義したら,どうせ == と != はちょうど逆の出力をする以外ないはずなので
自動的に operator!= も定義してほしい.
テンプレートを使うと上手くいくらしく,グローバルなヘッダーに以下を書いておく.

template<class T, class F = decltype(!(std::declval<T>()==std::declval<T>()))>
F operator!=(T a, T b) {
  return !(a==b);
}
programming/cpp/class.txt · Last modified: 2022/05/25 08:01 by odagawa