質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1547閲覧

deleteができなくて困っています

gemfighter

総合スコア38

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/11/24 10:00

編集2020/11/24 10:38

C++

1#include <iostream> 2#include <fstream> 3#include <vector> 4#include <algorithm> 5#include <functional> 6#include <string> 7#include <iomanip> 8 9using namespace std; 10 11//基底クラス 12class Bottom 13{ 14public: 15 short x1; //描画領域 左上 X座標 2B 16 short y1; //描画領域 左上 Y座標 2B 17 short x2; //描画領域 右下 X座標 2B 18 short y2; //描画領域 右下 Y座標 2B 19 long foreColor; //前景色 4B 20 long backColor; //背景色 4B 21 22 int recg; //派生クラス認識 23 24 void get(char h2, char h3, char h4, char h5, char h6, char h7, char h8, char h9, char h10, char h11, char h12, char h13, char h14, char h15, char h16, char h17); 25 26 //値取得 27 virtual void get2(); 28 29 void get3(int i); 30 31 //表示 32 virtual void LK(); 33 34 //コンストラクタ 35 Bottom(); 36 37 //デストラクタ 38 virtual ~Bottom(); 39}; 40 41//直線 42class StraightLine : public Bottom 43{ 44public: 45 46 char lineKind; //線種(0:実線、1:点線) 47 short startX; //描画開始 X座標 2B 48 short startY; //描画開始 Y座標 2B 49 short endX; //描画終了 X座標 2B 50 short endY; //描画終了 Y座標 2B 51 52 //コンストラクタ 53 StraightLine(); 54 55 //デストラクタ 56 ~StraightLine(); 57 58 //値取得 59 void get2(char h18, char h20, char h21, char h22, char h23, char h24, char h25, char h26, char h27); 60 61 //表示 62 void LK(); 63}; 64 65//基底コンストラクタ 66Bottom::Bottom() 67{ 68 69} 70 71//基底デストラクタ 72Bottom::~Bottom() 73{ 74 75} 76 77//基底表示 78void Bottom::LK() { 79 cout << "ボトムやで" << endl; 80} 81 82void Bottom::get(char h2, char h3, char h4, char h5, char h6, char h7, char h8, char h9, char h10, char h11, char h12, char h13, char h14, char h15, char h16, char h17) { 83 //unsigned使ってるのは、符号なしでbitを移動させたいから 84 85 //描画領域 左上 X座標 86 x1 = (unsigned char)h3; 87 x1 <<= 8;//左に8ビット移動 88 x1 = (x1 | (unsigned char)(h2 & 0xff));//データを連結 89 90 //描画領域 左上 Y座標 91 y1 = (unsigned char)h5; 92 y1 <<= 8;//左に8ビット移動 93 y1 = (y1 | (unsigned char)(h4 & 0xff));//データを連結 94 95 //描画領域 右下 X座標 96 x2 = (unsigned char)h7; 97 x2 <<= 8;//左に8ビット移動 98 x2 = (x2 | (unsigned char)(h6 & 0xff));//データを連結 99 100 //描画領域 右下 Y座標 101 y2 = (unsigned char)h9; 102 y2 <<= 8;//左に8ビット移動 103 y2 = (y2 | (unsigned char)(h8 & 0xff));//データを連結 104 105 //前景色 106 foreColor = (unsigned char)h13; 107 foreColor <<= 8;//左に8ビット移動 108 foreColor = (foreColor | (unsigned char)(h12 & 0xff));//データを連結 109 foreColor <<= 8;//左に8ビット移動 110 foreColor = (foreColor | (unsigned char)(h11 & 0xff));//データを連結 111 foreColor <<= 8;//左に8ビット移動 112 foreColor = (foreColor | (unsigned char)(h10 & 0xff));//データを連結 113 114 //背景色 115 backColor = (unsigned char)h17; 116 backColor <<= 8;//左に8ビット移動 117 backColor = (backColor | (unsigned char)(h16 & 0xff));//データを連結 118 backColor <<= 8;//左に8ビット移動 119 backColor = (backColor | (unsigned char)(h15 & 0xff));//データを連結 120 backColor <<= 8;//左に8ビット移動 121 backColor = (backColor | (unsigned char)(h14 & 0xff));//データを連結 122} 123 124//基底値取得 125void Bottom::get2() { 126 127} 128 129void Bottom::get3(int i) { 130 recg = i; 131} 132 133//直線コンストラクタ 134StraightLine::StraightLine() 135{ 136 x1 = 0; 137 y1 = 0; 138 x2 = 0; 139 y2 = 0; 140 foreColor = 0; 141 backColor = 0; 142 recg = 0; 143 lineKind = 0; 144 startX = 0; 145 startY = 0; 146 endX = 0; 147 endY = 0; 148} 149 150//直線デストラクタ 151StraightLine::~StraightLine() 152{ 153 154} 155 156 157 158//直線値取得 159void StraightLine::get2(char h18, char h20, char h21, char h22, char h23, char h24, char h25, char h26, char h27) 160{ 161 lineKind = h18;//線種 162 163 //描画開始 X座標 164 startX = (unsigned char)h21; 165 startX <<= 8;//左に8ビット移動 166 startX = (startX | (unsigned char)(h20 & 0xff));//データを連結 167 168 //描画開始 Y座標 169 startY = (unsigned char)h23; 170 startY <<= 8;//左に8ビット移動 171 startY = (startY | (unsigned char)(h22 & 0xff));//データを連結 172 173 //描画終了 X座標 174 endX = (unsigned char)h25; 175 endX <<= 8;//左に8ビット移動 176 endX = (endX | (unsigned char)(h24 & 0xff));//データを連結 177 178 //描画終了 Y座標 179 endY = (unsigned char)h27; 180 endY <<= 8;//左に8ビット移動 181 endY = (endY | (unsigned char)(h26 & 0xff));//データを連結 182} 183 184//直線表示 185void StraightLine::LK() { 186 cout << "描画領域(X1,Y1,X2,Y2) 前景色,背景色 線種   描画開始,終了" << endl; 187 cout << "\"直線 [" << setfill(' ') << right << setw(4) << dec << x1 << "," << setfill(' ') << right << setw(4) << dec << y1 << "]" 188 << " - [" << setfill(' ') << right << setw(4) << dec << x2 << ", " << setfill(' ') << right << setw(4) << dec << y2 << "]" 189 << " [0x" << setfill('0') << setw(6) << hex << foreColor << "] [0x" << setfill('0') << setw(6) << hex << backColor << "]"; 190 191 192 if (lineKind == 0) { 193 cout << " 実線 "; 194 } 195 else { 196 cout << " 点線 "; 197 } 198 cout << "[" << setfill(' ') << dec << setw(4) << startX << ", " << setfill(' ') << dec << setw(4) << startY << "]"; 199 cout << "[" << setfill(' ') << dec << setw(4) << endX << ", " << setfill(' ') << dec << setw(4) << endY << "]"; 200 201 202 //printf("[%4d,%4d] - [%4d,%4d]\"\n",startX, startY, endX, endY); 203 cout << endl; 204 cout << endl; 205} 206 207int main(){ 208 //直線用インスタンス 209 StraightLine* straightine; 210 211 //直線出力用インスタンス 212 Bottom* straightine2; 213 try { 214 straightine2 = new StraightLine; 215 } 216 catch (std::bad_alloc& e) { 217 // メモリ確保に失敗 218 std::cout << e.what() << std::endl; 219 } 220 221 std::vector<Bottom*> bases;//全部入れるテーブル 222 223 224 //直線バッファ容量確保 225 try { 226 straightine = new StraightLine[2]; 227 } 228 catch (std::bad_alloc& e) { 229 // メモリ確保に失敗 230 std::cout << e.what() << std::endl; 231 } 232 233 //インスタンスに値を格納 234 straightine->get(27, 1, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0); 235 straightine->get2(0, 0, 0, 0,0, 0, 0, 0, 0); 236 straightine->get3(1); 237 238 straightine->get(27, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 239 straightine->get2(0, 0, 0, 0, 0, 0, 0, 0, 0); 240 straightine->get3(1); 241 242 //ベクターに値をプッシュ 243 bases.push_back(straightine); 244 245 //ポインタをインクリメント 246 *straightine++; 247 248 for (auto it = std::begin(bases); it != std::end(bases); ++it) 249 { 250 //直線出力 251 if (dynamic_cast<StraightLine*>(*it) != 0) 252 { 253 straightine2 = dynamic_cast<StraightLine*>(*it); 254 straightine2->LK(); 255 } 256 } 257 258 //ここでstraightineとstraightine2をdeleteしたい 259 260 return 0; 261}

ポインタのクラスをdeleteできなくて困っています。
関数のところをコメントアウトするとできるみたいですが、原因が分かりません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

C++

1 straightine2 = new StraightLine; 2() 3 straightine = new StraightLine[1]; 4() 5 *straightine++; // 値を変更している 6() 7 straightine2 = dynamic_cast<StraightLine*>(*it); // 値を変更している 8() 9 //ここでstraightineとstraightine2をdeleteしたい

ポインタのクラスをdeleteできなくて困っています。

straightinestraightine2の値を変更しているためです。
別の変数に退避しておくなどして、deleteにはnewが返したアドレスを渡してください。


yumetodoさんもコメントされていますが、生のポインタは解放漏れや2重解放の原因となりますので
C++のコードではスマートポインタ(unique_ptr/shared_ptr/weak_ptr)の使用を検討してください。

投稿2020/11/24 10:30

編集2020/11/24 17:25
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yumetodo

2020/11/24 10:35

もっというとそもそもnewやdeleteを書くべきではありません。std::unique_ptrを利用してください。
SHOMI

2020/11/24 10:41

そうですね。生ポインタは開放漏れや2重解放の原因となりますし。 原因を聞かれたので理由だけ書きましたが…
gemfighter

2020/11/24 10:45

std::unique_ptrを書いたらdeleteは必要無くなりますか?
SHOMI

2020/11/24 10:58

std::unique_ptrが管理するため、deleteの呼び出しは不要です。 詳しくはリンク先を参照してください。
gemfighter

2020/11/24 11:57

あと、newのアドレスってどうやってdeleteに返しますか?
yumetodo

2020/11/24 15:41

> 別の変数に退避しておくなどして、deleteにはnewが返したアドレスを渡してください。 をもう一度お読みください
gemfighter

2020/11/25 08:29

わかりました。 もう一つ質問です。 今、shared_ptrで試しています。ですが、配列で作っていたら、それぞれの要素で関数が使えなかったり、ベクターにプッシュできなかったりして困っています。 どうやったら配列のそれぞれの要素を使えるようになりますか? shared_ptrの配列の使い方が検索してもあまり出てきませんでした。
yumetodo

2020/11/25 09:33

多分std::vector<std::shared_ptr<T>>のほうがいいと思いますが・・・。
SHOMI

2020/11/25 10:00

スマートポインタの使い方がわからないということでしたら、 deleteできないというこの質問とは別の話になりますので どの部分で躓いているのかコードを付けて別の質問として投稿しませんか。
gemfighter

2020/11/25 12:56

もう一つの質問投げましたので、もしよければそちらの方で回答お願いします。
guest

0

straightine2 は new をしてはいけないので、delete も不要。
straightine のみ、delete[] する。

C++

1#include <iostream> 2#include <vector> 3#include <iomanip> 4 5using namespace std; 6 7class Bottom { //基底クラス 8public: 9 short x1; //描画領域 左上 X座標 2B 10 short y1; //描画領域 左上 Y座標 2B 11 short x2; //描画領域 右下 X座標 2B 12 short y2; //描画領域 右下 Y座標 2B 13 long foreColor; //前景色 4B 14 long backColor; //背景色 4B 15 16 int recg; //派生クラス認識 17 18 void get(char h2, char h3, char h4, char h5, 19 char h6, char h7, char h8, char h9, 20 char h10, char h11, char h12, char h13, 21 char h14, char h15, char h16, char h17); 22 virtual void get2(); //値取得 23 void get3(int i); 24 virtual void LK(); //表示 25 Bottom(); //コンストラクタ 26 virtual ~Bottom(); //デストラクタ 27}; 28 29class StraightLine : public Bottom { //直線 30public: 31 char lineKind; //線種(0:実線、1:点線) 32 short startX; //描画開始 X座標 2B 33 short startY; //描画開始 Y座標 2B 34 short endX; //描画終了 X座標 2B 35 short endY; //描画終了 Y座標 2B 36 37 StraightLine(); //コンストラクタ 38 ~StraightLine(); //デストラクタ 39 void get2(char h18, 40 char h20, char h21, char h22, char h23, 41 char h24, char h25, char h26, char h27); //値取得 42 void LK(); //表示 43}; 44 45Bottom::Bottom() { } //基底コンストラクタ 46Bottom::~Bottom() { } //基底デストラクタ 47void Bottom::LK() { cout << "ボトムやで" << endl; } //基底表示 48 49using uc = unsigned char; 50 51short val2(char a, char b) { return uc(b)<< 8 | uc(a); } 52 53long val4(char a, char b, char c, char d) { 54 return uc(d)<<24 | uc(c)<<16 | uc(b)<< 8 | uc(a); 55} 56 57void Bottom::get(char h2, char h3, char h4, char h5, 58 char h6, char h7, char h8, char h9, 59 char h10, char h11, char h12, char h13, 60 char h14, char h15, char h16, char h17) { 61 x1 = val2(h2, h3), y1 = val2(h4, h5); 62 x2 = val2(h6, h7), y2 = val2(h8, h9); 63 foreColor = val4(h10, h11, h12, h13); 64 backColor = val4(h14, h15, h16, h17); 65} 66 67void Bottom::get2() { } 68void Bottom::get3(int i) { recg = i; } 69 70StraightLine::StraightLine() //直線コンストラクタ 71{ 72 x1 = y1 = x2 = y2 = 0; 73 foreColor = backColor = 0; 74 recg = lineKind = 0; 75 startX = startY = endX = endY = 0; 76} 77 78StraightLine::~StraightLine() { } 79 80void StraightLine::get2(char h18, 81 char h20, char h21, char h22, char h23, 82 char h24, char h25, char h26, char h27) 83{ 84 lineKind = h18; 85 startX = val2(h20, h21), startY = val2(h22, h23); 86 endX = val2(h24, h25), endY = val2(h26, h27); 87} 88 89//直線表示 90void StraightLine::LK() 91{ 92 cout << "描画領域(X1,Y1,X2,Y2) 前景色,背景色 線種   描画開始,終了" 93 << endl << setfill(' ') << right 94 << "\"直線 [" << setw(4) << x1 << "," << setw(4) << y1 << "]" 95 << " - [" << setw(4) << x2 << ", " << setw(4) << y2 << "]" 96 << hex << setfill('0'); 97 << " [0x" << setw(6) << foreColor << "] [0x" << setw(6) << backColor << "]" 98 << dec << setfill(' '); 99 << (lineKind ? " 点線 " : " 実線 ") 100 << "[" << setw(4) << startX << ", " << setw(4) << startY << "]" 101 << "[" << setw(4) << endX << ", " << setw(4) << endY << "]" 102 << endl << endl; 103} 104 105int main() 106{ 107 StraightLine* straightine = new StraightLine[2]; //直線用インスタンス 108 std::vector<Bottom*> bases; //全部入れるテーブル 109 110 //インスタンスに値を格納 111 straightine[0].get(27, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 112 straightine[0].get2(0, 0, 0, 0, 0, 0, 0, 0, 0); 113 straightine[0].get3(1); 114 115 straightine[1].get(27, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 116 straightine[1].get2(0, 0, 0, 0, 0, 0, 0, 0, 0); 117 straightine[1].get3(1); 118 119 //ベクターにポインタをプッシュ 120 bases.push_back(straightine); 121 bases.push_back(straightine + 1); 122 123 for (auto it = std::begin(bases); it != std::end(bases); ++it) { 124 Bottom* straightine2 = dynamic_cast<StraightLine*>(*it); 125 if (straightine2) straightine2->LK(); 126 } 127 128 delete[] straightine; 129 130 return 0; 131}

名前がひどい。
基底は Bottom ではなく Base。vector は bases にしていますが。
StraightLineクラスのインスタンスを指す変数が straightine とは?
値を格納するのに、get、get2、get3 とは?
Base の virtual get2() と StraightLine の get2(...) は引数の数が異なるので
オーバーライドされません。表示の virtual LK() はオーバーライドされますが。
LK() はオーバーライドされるので、dynamic_cast も straightine2 も不要です。
(*it)->LK(); で十分。

投稿2020/11/25 11:54

編集2020/11/25 12:21
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問