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

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

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

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

Q&A

解決済

2回答

5821閲覧

C++継承と変数の共有について、初歩的なことですが、理想的な組み込みか確認をお願いいたします。

seri

総合スコア422

C++

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

0グッド

0クリップ

投稿2016/09/10 16:54

編集2016/09/10 17:01

4つのヘッダファイルがあるとします
Main.h
Base.h
Sean1.h
Sean2.h

さらに3つのソースファイルがあるとします
Main.cpp
Sean1.cpp
Sean2.cpp

Sean1とSean2はBaseを継承しており、Main内で以下のような呼び出しを行います

C++

1/***Main.cpp***/ 2#include "Base.h" 3void main(){ 4Base* se01=new Sean1(); 5Base* se02=new Sean2(); 6}

Base内には以下のような記述があります。

C++

1/***Base.h***/ 2public: 3int ID;

これでMain内でのse01とse02で
se01->ID
などとすれば共有のIDが利用できますが、これだと重複問題やメモリリークの原因になりそうで不安です、ここではint型ですが、voidや配列となると不安です。。

PS
ちなみにこのサイトを見て気になりました(http://stlalv.la.coocan.jp/Header.html),サイト内ではインクルードでしたが、ポインタや継承が絡むと、、、、

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんにちは。

これでMain内でのse01とse02で

se01->ID
などとすれば共有のIDが利用できますが

se01->ID と se02->IDは別の領域に記録されますので、共有されていません。

クラスのメンバは常にnewする度に領域が確保されることはご存知と思います。
基底クラスのメンバも派生クラスに継承されてしまうので、派生クラスのメンバと同じように振る舞います。
従って、基底クラスのメンバでも派生クラスをnewする度に領域が確保されますので、se01->ID と se02->IDは異なる領域です。共有されていません。


【ところで】
C++ではヘッダ・ファイル != クラスです。
Base.hの中にclass Base {};を入れることができますが、更にclass foo {};やclass baz {};など、複数のクラスを入れることができますし、関係の深いクラスは同じファイルに入れることが多いです。(1つのファイルに1つのクラスしか入れないという習慣をC++では見たことありません。)

今回のケースの場合、例えば、下記のようなソースでも状況を説明できます。

main.cpp

C++

1#include <iostream> 2class Base 3{ 4public: 5 int ID; 6}; 7class Sean1 : public Base { }; 8class Sean2 : public Base { }; 9 10int main() 11{ 12 Base* se01=new Sean1(); 13 Base* se02=new Sean2(); 14 se01->ID=1; 15 se02->ID=2; 16 std::cout << "se01->ID=" << se01->ID << "\n"; 17 std::cout << "se02->ID=" << se02->ID << "\n"; 18 return 0; 19}

因みに、IDを共有したい場合ですが、状況に応じて実に様々な方法がありますので、もし、共有方法を知りたい場合は、別途質問を立てて詳しい状況を説明された方が良いと思います。

投稿2016/09/10 18:33

Chironian

総合スコア23272

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

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

0

そもそも共有のIDになりません。異なるオブジェクトにおける同一メンバになるだけです。

異なるオブジェクトでメンバを共有するならばstatic変数にするなりしないといけません。ちなみにこれは継承は関係ありません。ついでに、メモリリークを心配されておりますがメンバはポインタでないので、オブジェクトの開放処理を間違えない限りこの心配はありません。

多分、仰る文面からして「メンバをポインタにして同一のものを参照する仕組みにしたい」ということだと思います。そうするとほとんど内容を変えないといけないです。

投稿2016/09/10 17:05

HogeAnimalLover

総合スコア4830

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

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

seri

2016/09/10 17:21

なるほど、Base内のID(に、仮に値を与えた場合)はSean1、Sean2では同じ値でも、アドレスが違うとゆうことですね。 「メンバをポインタにして同一のものを参照する仕組みにしたい」とゆう実装でしたら確かにそのとおりだと思います しかし今回は、Baseのヘッダ内に関数処理を記述し、Sean1やSean2で、Baseのヘッダによって計算された戻り値を、Sean1Sean2内に記述する関数によってそれぞれ別々の計算に使用したいだけです。 この場合、Sean1、Sean2がBaseから継承する値は同じでも、アドレスは違います、そのためメモリリークの原因になるか不安とゆうわけです 説明不足でした。
HogeAnimalLover

2016/09/10 17:56

失礼ながら余計に質問の意図がわからなくなりました。 ちなみに、継承によって引き継ぐものは「値」でも「アドレス」でもありません。この場合は「IDという名のint型メンバ変数が存在する」という性質を引き継ぐだけです。当然アドレスは別ですし、値も同一とは限りません(値は同一になることもありえます)。 いずれにしろポインタ型ではないので、メンバ単独のメモリリークは発生しえません(オブジェクト本体の解体が適切であれば)。 まあ、プログラムの作りかけのようですし、先に作ってみればいいと思いますよ。思いの通りに動くことはないでしょうが。(質問説明の方が間違っている可能性はあります)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問