C++の質問です。クラスの中でクラスをベクターで使うことはできますでしょうか?
画像にペイントしたものをラインごとに保存するプログラムを作っています。
わからないことは
1、ベクターで宣言したクラスの中身を個別にアクセスしたい。
たとえば linesのpointにはA lineにはBといようにアクセスしたいです。
説明がうまくできませんがアドバイスいただけたら助かります。
以下がソースになります。
=line.h=========================================================
class paintedline{
public:
//左上座標
Tvector2<int> point;
//上下左右の保存
int top,botton,left,right;
//線の格納
vector<Tvector3<int>> line;
paintedline();
};
=linegroup.h=========================================================
#include "icg.h"
#include"line.h"
class line_group{
float choosing_line;
public:
vector<paintedline> lines;
line_group();
//線を保存--------------クリックしてから離すまで
void saveline(Tvector2<int>point, vector<Tvector3<int>> line);
//線を決定--------------クリックして線を決定
int return_line(Tcolor4<float> color);
//線を移動
void move_line(Tvector2<int>pa, Tvector2<int>pb);
//線を削除
void delete_line();
//すべての線をpaintedに合成
void synthesizing_lines();
};
=linegroup.cpp=========================================================
#include"linegroup.h"
#include"line.h"
line_group::line_group(){
}
//線を保存--------------クリックしてから離すまで
void line_group::saveline(Tvector2<int>point, vector<Tvector3<int>> line){
//線の四隅を保存
for(int i=0; i<(int)line.size(); i++){
if(top>line.y) top = line.y;
if(botton<line.y) botton = line.y;
if(left>line.x) left = line.x;
if(right<line.x) right = line.x;
}
//書かれた線を保存
lines.push_back(line)
}
//線を決定----------------クリックして線を決定
int line_group::return_line(Tcolor4<float> color){
choosing_line = color.r// rに格納したばんごうを決定
return choosing_line
}
//線を移動
void line_group::move_line(Tvector2<int>pa, Tvector2<int>pb,){
int x = abs(pa.x - pb.x);
int y = abs(pa.y - pb.y);
lines.at(n).point = (x,y);
synthesizing_lines();
}
//線を削除
void line_group::delete_line(){
cout<<"deleteするならdを押してください。"<<endl;
lines.erace(choosing_line);
}
No.1
- 回答日時:
「クラスの中でクラスをベクターで使うこと」はできて当然. vector のインターフェイスはそんなに変態ちっくなものじゃないので, ここで使うくらいなら「こんな感じかな」と単純に考えればだいたいできるはず.
でこのプログラムが何をしたいのかさっぱりわからんのだけど, 少なくとも
void line_group::saveline(Tvector2<int>point, vector<Tvector3<int>> line)
の中身が*あまりにもおかしい*ことはわかる.
むしろ「line.x」などと書けると考えた理由を知りたい.
自分自身理解していないため、質問が不明確になってすみません。
Tvector3は自分で作った3つの変数を持つ構造体です。
line.xで変数をとりだしています。
上手く伝えられるように、理解できるように自分自身もっと勉強をします。
No.2
- 回答日時:
関数1個しか書かないけど、こんな感じでどうでしょう。
//線を保存--------------クリックしてから離すまで
void line_group::saveline(Tvector2<int>point, vector<Tvector3<int>> line){
// lineが空なら何もしない
if(line.empty()) return;
paintedline pl;
//線の四隅を保存
for(int i=0; i<(int)line.size(); i++){
// 最初のループでは四隅の値が不定なので初期化
if(i == 0){
pl.top = pl.bottom = line[i].y;
pl.left = pl.right = line[i].x;
continue;
}
if(pl.top>line[i].y) pl.top = line[i].y;
if(pl.botton<line[i].y) pl.botton = line[i].y;
if(pl.left>line[i].x) pl.left = line[i].x;
if(pl.right<line[i].x) pl.right = line[i].x;
}
pl.point = point;
// lineは値渡しなので変更しても呼び出し元には影響しない
pl.line.swap(line);
//書かれた線を保存
lines.push_back(pl)
}
……ただし、自分ならばこうします。
=line.h=
#ifndef(LINE_H)
#define LINE_H
class paintedline{
private:
//左上座標
Tvector2<int> point_;
//上下左右の保存
int top_,botton_,left_,right_;
//線の格納
vector<Tvector3<int>> line_;
public:
paintedline(const Tvector2<int>& point, const vector<Tvector3<int>>& line);
// コピーコンストラクタと代入演算子は(多分必要だが文字数制限で入らないので)省略
//左上座標
const Tvector2<int>& get_point() const {return point_;};
//上下左右
int get_top() const {return top_;};
int get_bottom() const {return botton_;};
int get_left() const {return left_;};
int get_right() const {return right_;};
//線
const vector<Tvector3<int>>& get_line() const {return line_;};
}
#endif//LINE_H
=line.cpp=
#include"line.h"
paintedline::paintedline(const Tvector2<int>& point, const vector<Tvector3<int>>& line)
:point_(point), line_(line)
{
if(line.empty()){
top_ = botton_ = left_ = right_ = 0;
return;
}
top_ = bottom_ = line.begin()->y;
left_ = right_ = line.begin()->x;
vector<Tvector3<int>>::iterator ite = line_.begin();
ite++;
for(;ite != line_.end(); ite++){
if(top_>ite->y) top_ = ite->y;
if(botton_<ite->y) botton_ = ite->y;
if(left_>ite->x) left_ = ite->x;
if(right_<ite->x) right_ = ite->x;
}
};
=linegroup.cpp=
//線を保存--------------クリックしてから離すまで
void line_group::saveline(const Tvector2<int>& point, const vector<Tvector3<int>>& line){
lines.push_back(paintedline(point, line);
}
私の不十分な説明と、下手なコードで理解していただけたようでとても感謝しています。
// lineは値渡しなので変更しても呼び出し元には影響しない
pl.line.swap(line);とありますが
pl.line = line;ではだめでしょうか??
またhitomuraさんが1から作ったコードと、改善していただいたコードの違いは速度の問題ですか?:iterator ite = line_.begin();などのあたりはまだ勉強したことがなかったです。
分かりやすい説明で助かります。ありがとうございます。
No.3
- 回答日時:
Tvectorとか書いてあるのがよくわかりませんが、std::vectorなら動的なサイズ変更が可能であることを除けば扱い方は普通の配列とほとんど変わりません。
ですからクラス内にvectorを持つことも、クラスをvector化することももちろん普通にできます。
#ただし自作クラスの場合はコピーコンストラクタを書いておいた方が無難。
AとかBとかいう話はもっと具体的に書いてもらわないと何とも言い難いんですが、個別アクセスというのは「vectorの各要素にアクセス」とは何か違うんでしょうか?
No.4ベストアンサー
- 回答日時:
>// lineは値渡しなので変更しても呼び出し元には影響しない
>pl.line.swap(line);とありますが
>pl.line = line;ではだめでしょうか??
それでもOKです。速度の問題が無ければ。
swap()はvectorが内部に持っているデータを、引数として渡された別のvectorと交換するメソッドです。
vectorの内部構造についてはさまざまですが、たいていの場合、動的確保されたメモリ領域へのポインタとその領域を管理するのに必要なデータで構成されています。
単なるコピーの場合、(必要なら)現在保持している領域の開放→コピー元と同じ大きさの領域確保→各要素のコピーという処理が行われます。これらはいずれも遅い処理です。
それに対して、swap()の場合、ポインタおよび管理データの交換だけなので上記と比較すると早い処理です。
それゆえ、コピー元を壊してもいいならばswap()のほうがコピー速度は速いです。
#ひょっとしたらとんでもない説明ミスがあるかもしれないので、その場合は訂正お願いします>ほかの回答者様
>またhitomuraさんが1から作ったコードと、改善していただいたコードの違いは速度の問題ですか?
内部処理については以下に書いたとおり速度の問題です。
しかし、追加用のデータ作成処理をpaintedlineクラスに移したのは、そのデータ作成方法はpaintedlineクラスだけが知っていればいいことであるためです。
また、paintedlineクラスの変数に直接アクセスできないようにしたのは、これらを外部から勝手に変更させないためです。
このあたりはオブジェクト指向プログラミングの原則の一つのカプセル化の基礎です。
>:iterator ite = line_.begin();などのあたりはまだ勉強したことがなかったです。
これはイテレーターといって、vectorの要素を指すためのクラスです。vectorの各要素に対するループを回すならばイテレーターを使ったほうが効率的になります。
今回の場合上下左右の初期値を決めるため特殊なことをやっていますが、
vector<Hoge> hoge;
// === hogeに要素を追加 ===
for(vector<Hoge>::iterator ite = hoge.begin();ite != hoge.end(); ite++){
// 各要素に対する処理:要素のデータはポインタと同じように->で取得する
}
という具合にすれば最初から最後までの要素に対するループを回せます。
STLの効率的な使い方についてはスコット・メイヤーズの『Effective STL』にまとめられていますので、一読されることをお勧めします(参考URL:Amazon.co.jpの同書ページへのリンク)。
ただ、STLの入門書ではないため、STLの基礎についてはほかの本を読んだほうがいいでしょう。
参考URL:http://www.amazon.co.jp/dp/4894714108/
遅くなりましたが,詳しい説明ありがとうございました.
なんとか目的のものが完成できました.紹介していただいた本も確認してみます.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- MySQL 何にかが違うから エラーなんでしょうね! 2 2022/09/18 05:28
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- その他(プログラミング・Web制作) 十進BASICでの再帰についての質問です。 2 2022/11/18 09:17
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
相手側の携帯が電源切れてる時...
-
1コールだけ鳴るけど切れる電話...
-
face book で女性の方からline ...
-
いきなりラインのトークに「新...
-
LINE追加で「該当するユーザー...
-
ラインナップとラインアップは...
-
ある男子から、ライン追加され...
-
Windowsのバッチファイルで正規...
-
LINEで好きな人が「笑」を全然つ...
-
酔っ払って送られてきたlineが...
-
教えてください
-
あの噂の世界三大チェーンメー...
-
私がlineのアイコンを変更する...
-
lineのワン切り、なぜ?
-
3ヶ月前に別れた彼とはカカオト...
-
自分で人探し
-
高校生をセフレにしようとして...
-
質問です。 先日クラスの女子に...
-
法線(normal line)はなぜそう...
-
「一番上、真ん中、下」を示す英語
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
相手側の携帯が電源切れてる時...
-
1コールだけ鳴るけど切れる電話...
-
LINE追加で「該当するユーザー...
-
よく05(04)lineって見かけるん...
-
face book で女性の方からline ...
-
いきなりラインのトークに「新...
-
Windowsのバッチファイルで正規...
-
ある男子から、ライン追加され...
-
ラインナップとラインアップは...
-
生産ラインの品質を表す直行率...
-
遠くにいる友達とLINE交換する...
-
先輩のライン(男性)を追加した...
-
「一番上、真ん中、下」を示す英語
-
LINEで好きな人が「笑」を全然つ...
-
法線(normal line)はなぜそう...
-
新しいクラスメイト全員のLINE...
-
着信拒否、ラインブロックと解...
-
swift言語のprintln()関数で「p...
-
既婚女性にラインを聞くことに...
-
質問です。 先日クラスの女子に...
おすすめ情報