3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++の自作クラスを持つvectorがresizeできない時は

Posted at

はじめに

C++を書いていてふとしたミスで悩んでしまったので、原因と解決策を記します。

状況

自作クラスdim_3を持つvector<dim_3>resize()しようとするが、コンパイルエラーが起こる。ソースコードは以下。

main.cpp
# include <iostream>
# include <vector>
using namespace std;

class dim_3 {
	private:
		int x_;
		int y_;
		int z_;
	public:
		dim_3 (int x, int y, int z) : x_{x}, y_{y}, z_{z} {}
		inline void setX (int in) { x_ = in; }
		inline void setY (int in) { y_ = in; }
		inline void setZ (int in) { z_ = in; }
		inline int getX () const { return x_; }
		inline int getY () const { return y_; }
		inline int getZ () const { return z_; }
};

int main(){
	vector<dim_3> vc;
	vc.resize(10);
	cout << vc[4].getX() << " " << vc[4].getY() << " " << vc[4].getZ() << endl;
	return 0;
}
error
error: no matching constructor for initialization of 'dim_3'

dim_3を初期化するコンストラクタがないらしい。

cplusplusの該当ページには、

val
Object whose content is copied to the added elements in case that n is greater than the current container size.
If not specified, the default constructor is used instead.
Member type value_type is the type of the elements in the container, defined in vector as an alias of the first template parameter (T).

と記述されており、std::vector::resizeでは値の指定がない時はデフォルトコンストラクターを用いるとのこと。

原因

デフォルトコンストラクターを忘れていた。

解決方法1

デフォルトコンストラクターを作る。
冗長になるが、書き直したソースコードが以下。

main.cpp
# include <iostream>
# include <vector>
using namespace std;

class dim_3 {
	private:
		int x_;
		int y_;
		int z_;
	public:
		dim_3 () : x_{0}, y_{0}, z_{0} {}
		dim_3 (int x, int y, int z) : x_{x}, y_{y}, z_{z} {}
		inline void setX (int in) { x_ = in; }
		inline void setY (int in) { y_ = in; }
		inline void setZ (int in) { z_ = in; }
		inline int getX () const { return x_; }
		inline int getY () const { return y_; }
		inline int getZ () const { return z_; }
};

int main(){
	vector<dim_3> vc;
	vc.resize(10);
	cout << vc[4].getX() << " " << vc[4].getY() << " " << vc[4].getZ() << endl;
	return 0;
}

実行結果が以下。

output
0 0 0

解決方法2

初期化方法を指定する。
これは使いやすくないが、試したら動いたので一応記す。これを用いるとしてもデフォルトコンストラクターは作るべきである。ソースコードは以下。

main.cpp
# include <iostream>
# include <vector>
using namespace std;

class dim_3 {
	private:
		int x_;
		int y_;
		int z_;
	public:
		dim_3 (int x, int y, int z) : x_{x}, y_{y}, z_{z} {}
		inline void setX (int in) { x_ = in; }
		inline void setY (int in) { y_ = in; }
		inline void setZ (int in) { z_ = in; }
		inline int getX () const { return x_; }
		inline int getY () const { return y_; }
		inline int getZ () const { return z_; }
};

int main(){
	vector<dim_3> vc;
	vc.resize(10, dim_3(8,9,0));
	cout << vc[4].getX() << " " << vc[4].getY() << " " << vc[4].getZ() << endl;
	return 0;
}

実行結果が以下。

output
8 9 0

おわりに

今後は、デフォルトコンストラクターを忘れないよう注意します。

3
1
0

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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?