Cランタイムによるクラスオブジェクトの動的生成

解決


へろり  2007-08-25 02:16:27  No: 66108

Visual Studio .NET 2003にて開発しております。

struct HOGE{
    CString name;
    ・
    ・
    ・
};

HOGE *hoge;

というような構造体がありまして、これを配列で管理しようとしています。
また、この配列の要素数は可変長で必要に応じてにょきにょきと伸張したいと思っています。

しかし、realloc()関数でメモリを確保するとメンバ変数 CString name; の
コンストラクタが走らず、使用できません。

これまでずっとC言語を扱ってきたもので、ここ最近ようやくC++を触るように
なりました。

こういう場合C++ではどのようにするのが定石なのでしょうか。
どなたか知恵をお貸しください。


Blue  2007-08-25 02:39:18  No: 66109

reallocやmallocでは構造体内のクラスのコンストラクタが動いてくれません。

reallocやmallocを使うしかないのであれば、PODな構造体にするしかないでしょう。

もっとも、MFCならCArrayクラスで動的配列が実現できます。
(STLのstd::vectorもできる)
そのほうがメモリの開放を意識しなくてよいので使いやすいと思いますが
どうでしょうか?

#include <afxtempl.h>

CArray<Hoge, Hoge> hoge;
Hoge h;

h.name = _T("ほげ");
hoge.Add(h);

h.name = _T("もげ");
hoge.Add(h);

for (int i = 0; i < hoge.GetSize(); ++i)
{
    AfxMessageBox(hoge[i].name);
}


ポン太  2007-08-25 05:57:52  No: 66110

new/delete ですね。
CからC++ に移行するのであれば、
「美しいC++プログラミング見本帖」がおすすめです。

http://www.amazon.co.jp/%E7%BE%8E%E3%81%97%E3%81%84C-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A6%8B%E6%9C%AC%E5%B8%96-%E6%9F%8F%E5%8E%9F-%E6%AD%A3%E4%B8%89/dp/479810776X/ref=sr_1_2/250-6113688-5259421?ie=UTF8&s=books&qid=1187956568&sr=1-2


επιστημη  URL  2007-08-25 07:27:42  No: 66111

標準C++ライブラリなら

#include <vector>

std::vector<HOGE> hoges;

これでオシマイです。


επιστημη  URL  2007-08-25 08:48:48  No: 66112

// cl -MD -D_AFXDLL -EHsc hoge.cpp

#include <afxwin.h>
#include <iostream>
#include <vector>

struct HOGE {
  CString name;
};

int main() {
  std::vector<HOGE> hoge;
  HOGE h;
  h.name = "ほげ";
  hoge.push_back(h);
  h.name = "もげ";
  hoge.push_back(h);
  for ( int i = 0; i < hoge.size(); ++i ) {
    std::cout << static_cast<const char*>(hoge[i].name) << std::endl;
  }
}


へろり  2007-08-27 23:14:29  No: 66113

今ひとつテンプレートの構文が読めず後れてしまいました。

vectorを利用するのが私の要求を最も満たしてくれそうです。
レスをくださった皆様方どうもありがとうございました。

ところで、ポン太さんのレスより、new/deleteを挙げていますが、
new 演算子にはreallocのようなメモリを伸張する機能は
あるのでしょうか。

手持ちの入門書およびサイト等を見直しましたが、それを示唆するような
記述が見あたりません。

JISCよりC++の規格の方も目を通しましたが、規格書の言いたいことの
1/10も分かりません。

実際はどうなっているのでしょうか。
別問になりますがよろしくお願いします。


YuO  2007-08-27 23:32:35  No: 66114

> ところで、ポン太さんのレスより、new/deleteを挙げていますが、
> new 演算子にはreallocのようなメモリを伸張する機能は
> あるのでしょうか。

ないです。
そもそも,new演算子はoperator newを呼び出した後 (つまりはメモリを確保した後),コンストラクタを走らせるものですから。

可変長配列の実装は,
・new[]で必要量を確保
・要素数の増減があった場合は,new[]で確保して,代入して,delete[]で元の要素を削除
が基本になります。
実際のstd::vectorはもっと複雑なことをしていますが。


へろり  2007-08-28 23:07:05  No: 66115

> ないです。
> そもそも,new演算子はoperator newを呼び出した後 (つまりはメモリを確保した後),コンストラクタを走らせるものですから。

そうですか。  もしかしたらと思ったのですがやはりそうなのですね。

これで全ての疑問が氷解しました。
レスくださった皆様おつきあいいただきありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加