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

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

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

C++/CLIは、.NET Frameworkの共通言語基盤であるCLI向けにC++を拡張したプログラム言語です。前身のC++マネージ拡張と比較するとシンプルで分かりやすい構文になっており、高い可読性を持ちます。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Q&A

解決済

1回答

1566閲覧

クラスメンバのリストへの追加がしたい

wide_shallow_

総合スコア5

C++/CLI

C++/CLIは、.NET Frameworkの共通言語基盤であるCLI向けにC++を拡張したプログラム言語です。前身のC++マネージ拡張と比較するとシンプルで分かりやすい構文になっており、高い可読性を持ちます。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

0グッド

0クリップ

投稿2022/03/11 04:06

c++言語を勉強しているものです。windowsで動くシフト作成ソフトをvisualC++で作ろうとしているのですが、従業員のデータの管理がうまくいきません。

全体的な流れは作って楽しむプログラミング visual C++2019 超入門 という本を参考にしています。
https://shop.nikkeibp.co.jp/front/commodity/0000/P86510/

実装はこちらのサイトのやり方を参考にしています。

http://marupeke296.com/DXCLS_AutomationOfSaveLoad.html

そこで、

// 保存する変数の位置を指定
DATARECORD CPlayer::m_gDataRecord[] =
{
{TYPE_LOCAL, 0, 4} // m_iLevel
{TYPE_LOCAL, 4, 4} // m_bFlag
};

ここに相当する部分を書こうとしているのですが、m_gDataRecord[]をリストのポインタで宣言してしまっている(配列や普通のリストで書くとはまた違うエラーが出ました。) 為か、push_back で変数を追加しようと思っても

「式にはクラス型を使用する必要がありますが、型"std::list<DATARECORD,std::allocator<DATARECORD>>が使用されています」

というエラーメッセージが出てしまいます。

自分の中では、リストも固定長のアドレスなので、参照を使えばオブジェクトのオフセットからデータにアクセスすることができ、このセーブ方法を応用できると思ったのですが、どうもうまくいきません。

自分で調べてもよくわかりませんでした。独学でやっているので、今やっている事が正しいのかもよくわからず、五里霧中です。解決する方法があればご教示お願い致します。また、違うもっといい方法があればそれも教えていただきたいです。 よろしくお願いします。

以下、コードとバージョン情報になります。
------------------datastruct.h----------------------------------------------------------------------

#ifndef ING_DATASTRUCT
#define ING_DATASTRUCT

struct DATARECORD
{
char type; // データタイプ
int offset; // オフセット値
int size; // サイズ
};

#endif

------------------ datasv.cpp-----------------------------------------------------------------------

#ifndef INGD_DATASV
#define INGD_DATASV

#include<vector>
#include<list>
#include<string>
#include"datastruct.h"
using namespace std;

ref class datasv
{
public:

int ID; wstring* KanjiName; //kanji wstring* KataName; //katakana int Slevel; // skill level int perW; //how many attending per week vector<vector<vector<int >>>* attendable = &vector<vector<vector<int>>>(7, vector<vector<int>>(24, vector<int>(4))); //3D vector Attendable time table int Chour; //continuable hour int Cminutes; //continuable hour static list<DATARECORD>* m_gDataRecord; // 保存するデータ配列 int dataad() { *m_gDataRecord.push_back('a', 1, 2); //ここです。 return 0; }

};

#endif

環境
visual studio 2022
テンプレート
空のCLRプロジェクト

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

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

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

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

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

guest

回答1

0

ベストアンサー

演算子の結合は * よりも . のほうが優先順位が高いです。 つまり *m_gDataRecord.push_back('a', 1, 2); と書いてあれば *(m_gDataRecord.push_back('a', 1, 2)); というように解釈されます。 ポインタである m_gDataRecord が指す先のメンバを呼出すのであれば (*m_gDataRecord).push_back('a', 1, 2); と書くか m_gDataRecord->push_back('a', 1, 2); と書く必要があります。

また、 push_back は一引数の関数です。 格納したい要素ひとつを渡すものであって、三つの引数は渡せません。 この場合は DATARECORD 型のオブジェクトを構築してから渡す必要があります。 つまり m_gDataRecord->push_back(DATARECORD{'a', 1, 2}); という要領ですね。

C++ ではこういうときは emplace_back を使うのですが、 C++/CLI には emplace_back がないようですね……。


それと質問の主旨とは違うところですが

vector<vector<vector<int >>>* attendable = &vector<vector<vector<int>>>(7, vector<vector<int>>(24, vector<int>(4)));

は C++ 的には問題のある記述です。

このとき構築されたオブジェクトは式 (完全式) の終わりには解体されてしまうので解体済みのオブジェクトの場所が attendable に格納されてしまいます。 つまり attendable は無効なポインタです。

私は C++/CLI のことには明るくないですが、たぶん C++/CLI でも同様だと思います。 メモリ管理の仕組みは C++ と C++/CLI でかなり違うのでここでは細かいことは述べません。

投稿2022/03/18 06:29

SaitoAtsushi

総合スコア5444

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

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

wide_shallow_

2022/03/22 10:23

返信が遅くなり申し訳ございません、、、 丁寧な解説本当にありがとうございます。至らぬところばかりで恥ずかしいです、、精進して参ります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問