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

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

新規登録して質問してみよう
ただいま回答率
85.35%
ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

C++

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

Q&A

0回答

1508閲覧

ポインタからメンバ関数を呼び出したい

misosoupsoybeen

総合スコア0

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

C++

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

0グッド

0クリップ

投稿2021/09/24 06:14

編集2021/09/24 21:55

前提・実現したいこと

C++でポインタからメンバ関数を呼びすというプログラムを書きました。
コンパイルは通るものの実行結果が想定と違います。

本体で宣言したポインタからよそのファイルに定義されたメンバ関数を呼び出したのですが、うまくいきません。
出力結果は
hello from initialize
hello
が得られるかなと思いましたが、何も出力されませんでした。

初学者です。専門用語の言い回しなどまだよくわかっていないため上記の表現で伝わるかわかりません。すみません。自分ではこれ以上何をどうすればいいのかよくわからないのでどうかよろしくお願いします。お力をお貸しください。

該当のソースコード

C++

1ソースコード 2//test.cpp 3#include<iostream> 4#include "initialize.h" 5 6using namespace std; 7 8int main(){ 9 Initialize *p; 10 11 p=new Initialize; 12 p->hello(); 13 delete p; 14 15 cout << "hello"<<endl; 16 return 0; 17} 18 19ヘッダファイル 20//initialize.h 21#ifndef _initialize_h 22#define _initialize_h 23class Initialize{ 24 private: 25 public: 26 Initialize(); 27 ~Initialize(); 28 void hello(); 29}; 30#endif 31 32//initialize.cpp 33#include<iostream> 34#include "initialize.h" 35 36using namespace std; 37// 38Initialize::Initialize(){ 39} 40Initialize::~Initialize(){} 41 42void Initialize::hello(){ 43 cout <<"hello from initizelize"<<endl; 44} 45 46

試したこと

mainのポインタに関する記述をコメントアウトし、メンバ関数の呼び出しを変数から行ったら想定通りの結果が得られた。つまり、
hello from Initialize
hello
と出力しました。

  //Initialize *p; //p=new Initialize; //p->hello(); //delete p; Initialize init; init.hello(); cout << "hello"<<endl;

試したことその2(追記)

test.cppという名前をwakaran.cppに変え、makefileのtest部分をすべてwakaranに置換しました。

mingw32-make.exe

g++ -Wall -g wakaran.o initialize.o -o tesuto

./tesuto

文章は出てきませんでした。
その後、

mingw32-make.exe clean

をしてみたところ、

process_begin: CreateProcess(NULL, rm tesuto wakaran.o initialize.o, ...) failed.

make (e=2): wウスt@CェゥツゥワケB
makefile:11: recipe for target 'clean' failed
mingw32-make: *** [clean] Error 2

となったので、

rm *o
rm *exe

して再度実行してみたところ、やはりポインタを使うと文章は出力されませんでした。
いずれの場合も、ポインタを使わず変数を使うと想定通り文章が出力されました。その時毎回文章を微妙に変えましたがその通りに出力されました。

試したことその3(追記)

ポインタをよそのファイルのメンバ関数ではなく、本体で整数型の配列を指すポインタにしてみたところ、やはりhelloは出力しませんでした。

C++

1#include <iostream> 2using namespace std; 3 4int main(){ 5 6 cout<<"hello"<<endl; 7 8 int *p; 9 p=new int[10]; 10 delete p; 11 12 //int *p; 13 //p=(int *)malloc(sizeof(int)*10); 14 //free(p); 15}

配列の動的な確保にnewではなくmallocを使ったらhelloは出力されました。

C++

1#include <iostream> 2using namespace std; 3 4int main(){ 5 6 cout<<"hello"<<endl; 7 8 //int *p; 9 //p=new int[10]; 10 //delete p; 11 12 int *p; 13 p=(int *)malloc(sizeof(int)*10); 14 free(p); 15}

環境

実行環境はvisual studio codeを使っています。他にもMinGWやMSYS2を最近ダウンロードしました。(実行環境とはこういうのを指す言葉でしょうか?いまいち自信がありません)

実行手順

makefileを使っています。
内容はこうです。

//makefile tesuto: test.o initialize.o g++ -Wall -g test.o initialize.o -o tesuto test.o: test.cpp initialize.h g++ -Wall -g -c -I./ test.cpp -o test.o initialize.o: initialize.cpp initialize.h g++ -Wall -g -c -I./ initialize.cpp -o initialize.o clean: rm tesuto test.o initialize.o

mingw32-make.exe

./tesuto

で実行しています。

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

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

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

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

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

dodox86

2021/09/24 06:19

> コンパイルは通るものの実行結果が想定と違います。 具体的にどういう結果を想定していて、どういう結果になっているのかを質問本文中に修正、追記するかたちで明示してください。
misosoupsoybeen

2021/09/24 06:22

すみません。忘れていました。 追記しました。
can110

2021/09/24 06:28

当方環境では再現しません(どちらも同じく出力される) 「試したこと」で示されているコードを、もう一度前の状態に戻してビルド→実行しても再現しますか? それでも再現する場合は、コンパイル、実行手順、環境なども記載したほうがよいと思います。
yohhoy

2021/09/24 06:30

ソースコード記述それ自体に問題はなく、本来であれば期待通り動作するはずです。https://wandbox.org/permlink/iZbqbWAsVwWV7MfP 実行環境や確認手順などを明記されたほうが良いかもしれません。
misosoupsoybeen

2021/09/24 07:20

「試したこと」をした後、もう一度前の状態に戻しビルド→実行しても再現します。 その後もう一度「試したこと」を出力される文章を微妙に変えて実行したら、その文章が出力されました。
misosoupsoybeen

2021/09/24 07:21

文章は本体のもメンバ関数内のも変えました。
episteme

2021/09/24 07:22

Visual Studio 2022(preview) でも再現しません(期待通りに動きます)。
dodox86

2021/09/24 07:23

私も試してみましたが、皆さんが書かれているように、問題は再現しませんね。質問者さんの要望通りの出力を得られます。 単にファイルを保存していなかったとか、古い*.oとリンクしてしまっていたのではないでしょうか。一回 clean してみたらどうでしょう。コマンドラインだと「mingw32-make.exe clean」でしょうか。 出力ファイルは"tesuto"なのでまぁ大丈夫だと思うのですが、UN*X環境であれば"test"と言うコマンドがあります。こちらを動かしてしまってアレレ?という状況は意外とあるあるです。
fana

2021/09/24 08:38

main関数内の最初の行として(すなわち,Initialize *p; よりも前に) 何かを出力させる処理を追加してみたら,それは表示されるんでしょうか.
misosoupsoybeen

2021/09/24 08:43

やってみました。 何も出力しませんでした。
dodox86

2021/09/24 08:56

それはもうおかしいですね。ファイルを編集した後、保存して再コンパイルしてますでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問