継承されていないクラスのコンストラクターの呼び出し方(初学者)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: 継承されていないクラスのコンストラクターの呼び出し方(初学者)

Re: 継承されていないクラスのコンストラクターの呼び出し方(初学者)

#8

by keito94 » 6年前

ごめんなさい、質問の意味が僕にしかわかりませんでしたね…。知識不足がまたたたってしまいました。
しっかり、C言語とC++の勉強をし直してこようと思います。
一応この質問は解決とさせてください。

Re: 継承されていないクラスのコンストラクターの呼び出し方(初学者)

#7

by keito94 » 6年前

左辺値ウンタラカンタラは気のせいだったようです。訂正してください。
…でも、この例外の原因ならわかりますよね?
添付ファイル
質問.PNG
質問.PNG (5.38 KiB) 閲覧数: 4335 回

Re: 継承されていないクラスのコンストラクターの呼び出し方(初学者)

#6

by みけCAT » 6年前

keito94 さんが書きました:こういうことでしょうか?
違うと思います。
このコードはコンパイルが通り、明示的に初期化されていないポインタaをデリファレンスしたことによりSegmentation Faultが発生しましたが、
「左辺値ウンタラカンタラ」に該当しそうなエラーは得られませんでした。
また、

コード:

prog.cc: In function 'int main()':
prog.cc:21:7: warning: 'a' may be used uninitialized in this function [-Wmaybe-uninitialized]
  a->b = new B();//ここで何らかのエラーが発生する。
  ~~~~~^~~~~~~~~
という警告が出ました。

「左辺値ウンタラカンタラ」というエラーの原文をそのまま(ユーザー名などの個人情報は隠して)貼っていただけますか?

Re: 継承されていないクラスのコンストラクターの呼び出し方(初学者)

#5

by keito94 » 6年前

みけCAT さんが書きました: このエラーの解決法を聞きたければ、最小限の・自己完結した・確認可能なサンプルコードを提示してください。
こういうことでしょうか?

コード:

#include <iostream>
using namespace std;

class B {
public:
	B();
};

class A {
public:
	B* b;
};

B::B() {
	cout << "Bのコンストラクターが起動されました。" << endl;
}

int main(void) {
	A* a;
	cout << "Bのクラスのコンストラクターを起動します。" << endl;
	a->b = new B();//ここで何らかのエラーが発生する。
	return 0;
}

Re: 継承されていないクラスのコンストラクターの呼び出し方(初学者)

#4

by みけCAT » 6年前

No: 1のコードを適当に1個のソースコードにまとめ、コンパイルが通るようにしてみました。

コード:

#include <iostream>

class C{
public: /* Cのコンストラクタがprivateだったので、publicに変更 */
    C();
}; /* ;を追加 */

class A{
public:
    C* c;
    void Const(); /* ;を追加 */
};

class B{
public:
    A* a;
    B();
};

using namespace std;

void A::Const(){ /* ()を追加 */
    B* b; /* bの定義を追加 */
    cout << "コンストラクター起動!" << endl;
    b = new B();
    delete b;
}

int main(void){
    A a; /* *を取る */
    a.Const(); /* ();を追加 */
    return 0;
}

B::B(){
    cout << "違うクラスのコンストラクター" << endl;
    a->c = new C();//ここで左辺値ウンタラカンタラが出る。
}

C::C(){
    cout << "第三のコンストラクター。" << endl;
}
keito94 さんが書きました:ここで左辺値ウンタラカンタラが出る。
という場所ではCのコンストラクタがprivateというエラーは出たものの、「左辺値ウンタラカンタラ」のようなエラーは再現できませんでした。
このエラーの解決法を聞きたければ、最小限の・自己完結した・確認可能なサンプルコードを提示してください。

Re: 継承されていないクラスのコンストラクターの呼び出し方(初学者)

#3

by purin52002 » 6年前

こんばんは、今日の晩御飯は焼きそばです。

今回keitoさんがやっているのは

「今日はパンがたべたいな」「じゃあ焼きそばにするね^^」

のようなことです。
ごめんなさい、焼きそばがうれしくて調子に乗りました^^;

コード:


class A;//中身は省略
class B;
class C : public A;

class MyClass
{
public:
    A* a;
    A* b;
    A* c;
};


int main()
{
    MyClass obj;

    obj->a=new A();//ok
    obj->b=new B();//error
    obj->c=new C();//ok!

}
簡単に説明すると、
ポインタに違う型のポインタを代入しようとするからエラーになります。
(int*にchar*入れちゃダメ!みたいなイメージ)


詳しく説明すると

クラスの継承にはポインタを使います。
なぜポインタを使うのでしょうか?

それはポインタのメモリサイズが同じだからです。
じゃあ違う型のポインタ入れてもいいじゃん!
ダメなんです^p^詳しい理由は知りません^p^


じゃあなんで基底クラスのポインタに継承クラスのポインタを入れてもいいんですか?
基底クラスでできることは継承クラスでもできますよね?
じゃあ基底クラスの機能だけ使うっていうんなら特別に許してやろう^^
って感じで継承クラスのポインタを入れられるわけです。

正しい知識はググってください^^;
[hr]
まとめ

・ポインタに違う型のポインタを入れたらエラー
・基底クラスのポインタに継承クラスのポインタを入れるのはok!
・そのポインタでできることは基底クラスでできることのみ。
[hr]
訂正とお詫び

質問を読み直してみたところ、私の指摘がトンデモなことに気づきましたorz
例えるなら、ナポリタンを焼きそばと言い張るような、、、
すみません、黙ります^^;

Re: 継承されていないクラスのコンストラクターの呼び出し方(初学者)

#2

by Iseuma14 » 6年前

あなたのプログラムをそのままコピーしてVSに貼るとクラスAのConstの定義のところにカッコが付いていなかったり、aのヘッダのConstにセミコロンが付いていなかったり、Aのメンバでないbをnewしていたりと多くのエラーが排出され、実行ができませんでした。

これはあなたの実行環境にあるコードと同じものですか?
実行環境と同じコードをコピーペーストして貼ることをおすすめいたします。

継承されていないクラスのコンストラクターの呼び出し方(初学者)

#1

by keito94 » 6年前

C++の初歩的な質問すいません。以下のようなソースコードは継承されていないクラスから違うクラスで宣言されているクラスのコンストラクターを呼び出そうとしているものです。検索しても継承されているコンストラクターの情報しかありませんでした。コメントのようなエラーが出てしまいます。

A.cpp

コード:

#include <iostream>
#include "A.h"
#include "B.h"

using namespace std;

void A::Const{
	cout << "コンストラクター起動!" << endl;
	b = new B();
	delete b;
}
int main(void){
	A* a;
	a.Const
	return 0;
}
A.h

コード:

#pragma once
#include "C.h"
class A{
public:
	C* c;
	void Const()
};
B.h

コード:

#pragma once
class A
class C
class B{
public:
	A* a;
	B();
};
B.cpp

コード:

#include <iostream>
#include "C.h"
#include "B.h"
#include "A.h"

using namespace std;

B::B(){
	cout << "違うクラスのコンストラクター" << endl;
	a->c = new C();//ここで左辺値ウンタラカンタラが出る。
}
C.cpp

コード:

#include <iostream>
#include "C.h"
using namespace std;
C::C(){
	cout << "第三のコンストラクター。" << endl;
}
C.h

コード:

#pragma once
class C{
	C();
}
想定される結果はのは以下のとおりです。

コード:

コンストラクター起動!
違うクラスのコンストラクター。
第三のコンストラクター。

ページトップ