オブジェクトの作成と関数との関係を勉強していますが参照の使い方に関して質問させていただきたいと思います。
以下のような簡単なプログラムを作りました。
myclass.cpp myclass.h で記述されたクラスmyclassは整数を一つ持ち、show_value関数でその整数を表示し、say_heyで"hey"という文字を出力するというものです。
このクラスを利用するプログラムとしてmain.cppをつくりました。このなかには2つの関数が使われます。
-オブジェクトをつくりそれをオブジェクトとして返す関数(return_obj)
-オブジェクトをつくりそれの参照を返す関数(return_ref_obj)
これらの関数を用いてオブジェクトをつくり、そのオブジェクトを戻り値としてmainのなかでオブジェクトのshow_value関数で保持する整数を表示する、というものです。
myclass.h--------------------------------
class Myclass{
public:
int my_int;
Myclass();
~Myclass();
void show_value();
void say_hey();
};
myclass.cpp----------------------------------
#include "myclass.h"
#include <iostream>
using namespace std;
Myclass::Myclass(){};
Myclass::~Myclass(){};
void Myclass::show_value(){
printf("%d\n", my_int);
}
void Myclass::say_hey(){
printf("hey\n");
}
main.cpp------------
#include <iostream>
#include "myclass.h"
using namespace std;
//オブジェクトをつくりそれをオブジェクトとして返す関数(return_obj)
Myclass return_obj(int int_in){
Myclass myobject;
myobject.my_int = int_in; //引数をオブジェクトのmy_intに渡す
return myobject;
}
//オブジェクトをつくりそれの参照を返す関数(return_ref_obj)
Myclass& return_ref_obj(int int_in2){
Myclass myobject;
myobject.my_int = int_in2; //引数をオブジェクトのmy_intに渡す
Myclass& ref_of_myclass = myobject;
return ref_of_myclass;
}
void main(){
Myclass returned_obj = return_obj(1); //関数に1を渡し、1を保持するオブジェクトを作成
returned_obj.show_value(); //整数(1)表示
returned_obj.say_hey();
Myclass& ref_obj = return_ref_obj(2); //関数に2を渡し、2を保持するオブジェクトを作成し参照として受け取る
ref_obj.show_value(); //整数(2)表示
ref_obj.say_hey();
}
プログラムを実行した出力-------------------
1
hey
-858993460
hey
このようにオブジェクト自体を返してコピーしたもの(return_obj使用)はshow_valueでただしくオブジェクトに保持された数が表示されますが 参照でオブジェクトを返したもの(return_ref_obj使用)はアドレスのような数列が表示されます。
質問A
これはオブジェクトの参照を返す関数(return_ref_obj)でオブジェクトを作成しても、そのオブジェクトが関数の中でのみ実在しており、関数がおわるとその実体がなくなるためではないかと解釈しているのですがそれで正しいでしょうか?
質問B
関数でオブジェクトを作成してそれをプログラム本体に渡すときはreturn_objのようにオブジェクト自体をコピーしなければ参照などで渡すことはできないのでしょうか?
クラスと参照自体勉強を始めたばかりで色々と初歩的な間違いもあるとは思いますが、よろしくお願いします
No.2
- 回答日時:
rinkun さんがおっしゃるとおり、
「関数がおわるとその実体がなくなるため」
という理解で正しいです。
newしてポインタを返すほかには、関数内の自動変数を静的に宣言する方法があります。
シングルトンパターンになるんですかね。
こんな感じです。
class A& method()
{
static class A;
return A;
}
これなら、method() をreturnした後も class Aはなくならないので大丈夫なはずです。
また、呼び出し元でdeleteしなくても済みます。
ただし、複数の呼び出し元で、ひとつのインスタンスを共通して使用することになるので、その点は注意が必要です。
特に、起動後初回の呼び出しで class Aのコンストラクタが処理されるので、初回呼び出し時に複数スレッドから同時にアクセスされると例外が発生することがあります。
具体的なコードありがとうございます。勉強になりました。
new, staticなどは知識としては多少ありましたが、実際に使うのはちょっと躊躇してしまっていました。これからは積極的に使ってみようと思います。
No.1ベストアンサー
- 回答日時:
質問A:その理解で正しいです。
質問B:作ったオブジェクトを参照で返すのは止めた方が良いです。
オブジェクトをコピーで返しましょう。
あるいはnewで作ってポインタで返しましょう。
関数内で自動変数を宣言して作ったオブジェクトはその関数を終えると削除されるので、そこへの参照は懸垂参照という不正な状態になります。
newで作成したオブジェクトはdeleteするまで存在するので関数から返せます。このときは参照でなくポインタを返しましょう。参照を返すとdeleteが面倒です。
回答ありがとうございました。
ポインタはなにかと面倒そうなイメージもあり、参照が使えないかと思っていたんですがそうもいかないようですね。
今回のようなオブジェクトの有効な範囲というのは私がプログラミングでいまいち感覚がつかめていなかった部分なのですが、今回の件でとても勉強になりました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 3 2022/10/04 15:07
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# 至急教えてください! プログラミングの問題です! お願いします! 出力2と全く同じ出力をするように、 2 2022/06/22 23:10
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Excelで =EMBED("Acrobat Docu...
-
ワイルドカード<?>と型パラメー...
-
COMコンポーネントって何?
-
時間帯判定をする。
-
ビジュアルC++でボタンの有...
-
LISTBOXの内容が更新されま...
-
JqueryとPrototypeの比較
-
Vbで通常使用するプリンターを...
-
bmp画像をjpegやpng画像に圧縮...
-
JAVAからHTMLへ値を返す方法
-
パワーポイントのVBAでテキスト...
-
多人数のじゃんけんプログラム
-
ワードで画像をドロップすると...
-
Excel VBA : イコールになら...
-
newは明示的にした方が良いのか?
-
Google Apps Scriptの時刻の計算
-
オブジェクトに値を保持させる...
-
SQLException
-
シーケンス図のライフラインと...
-
開始日(Date型)から終了日(Date...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
パワーポイントのVBAでテキスト...
-
Excelで =EMBED("Acrobat Docu...
-
ワイルドカード<?>と型パラメー...
-
EXCEL VBAにて動的にCheckBOXを...
-
VBAのWindowオブジェクトとWork...
-
C#でフォームのオブジェクト名...
-
LISTBOXの内容が更新されま...
-
Object型からDouble型へのキャスト
-
JAVAからHTMLへ値を返す方法
-
COMコンポーネントって何?
-
ビジュアルC++でボタンの有...
-
戻り値がクラスオブジェクト
-
VBA 同じ名前のオブジェクトを...
-
ASP.net 教えてください!!(...
-
Vbで通常使用するプリンターを...
-
newは明示的にした方が良いのか?
-
CoCreateInstanceでエラーになる。
-
オブジェクトレベルとメタレベル
-
bmp画像をjpegやpng画像に圧縮...
-
Accessの連結・非連結オブジェ...
おすすめ情報