派生クラスへのポインタキャストについて

このQ&Aのポイント
  • 派生クラスへのポインタキャストはdynamic_castまたはstatic_castが必要です。
  • 基底クラスから派生クラスへのポインタキャストはdynamic_castまたはstatic_castが必要です。
  • ソースコードにおいてすべてのキャスト演算にエラーが出ており、キャストはできません。
回答を見る
  • ベストアンサー

キャストについて教えてください

基底クラスから派生クラスにポインタはキャストできないのでしょうか?? 以下のソースを実行したところすべてのキャスト演算において '初期化中' : 'CBase *' から 'CEx *' に変換できません。 base から derived へのキャストには、dynamic_cast または static_cast が必要です。 というエラーが出てしまいます。 これはキャストできないのでしょうか?? class CBase { public:     int base; }; class CEx : public CBase { public:     int ex; }; void main( void ) {   CBase* base = new CEx;   CEx* e1 = dynamic_cast<CBase*>( base );   CEx* e2 = static_cast<CBase*>( base );   CEx* e3 = reinterpret_cast<CBase*>( base );   CEx* e4 = (CBase*)( base ); }

  • 0xEF
  • お礼率59% (193/327)

質問者が選んだベストアンサー

  • ベストアンサー
  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

参考になりそうなページ http://www.geocities.jp/ky_webid/cpp/language/024.html >  CEx* e4 = (CBase*)( base ); の部分は、   CEx* e4 = (CEx*)( base ); の間違いですか。

0xEF
質問者

お礼

まったくそのとおりでした。 お騒がせしました。

関連するQ&A

  • dynamic_castの必要性

    dynamic_castの必要性がいまいち良く分かりません。 必ずしも必要ないのかも、とも思います。 例えば以下のような場合。 class B { public: virtual void f(){cout << "bbb" << endl;} }; class D : public B { public: void f(){cout << "aaa" << endl;} }; int main() { B b, *bp; D d, *dp; bp = &d; bp->f(); dp = dynamic_cast<D *>(bp); //(1) // dp = &d; //(2) dp->f(); return 0; } (1)と(2)はどちらでも同じ意味だと思います。 (2)でいいのなら、(1)のダイナミックキャストをわざわざ用意する必要はないと思います。 どなたかダイナミックキャストの必要性を教えていただけないでしょうか。

  • 多態性を利用して派生クラスの関数を呼びたい

    環境はVS2013,言語はC++です. 基底クラス側で,基底クラスのポインタを引数に受ける仮想関数を宣言し, 派生クラスでその実装をします. 派生クラス側で引数に派生クラスのポインタを受けて,派生クラスのメンバにアクセスできるようにしたいのです. 作成したサンプルを下記に示します. Hello()は関係ありません. また,これはあくまで簡略化したサンプルなだけなので,thisポインタからメンバにアクセスすればよいというものではありません. #include <iostream> class Base { public: int i; Base() :i(0) {} virtual void print(Base *p) { std::cerr << "Base : " << i << std::endl; } virtual void hello() = 0; }; class Super : public Base { public: int x; Super() : x(1) {} void print(Super *p) { std::cerr << "Super : " << p->x << std::endl; } void hello() { std::cerr << "hello" << std::endl; } }; int main(void) { Base *p; p = new Super; p->print(p); } 上記を実行した結果,Base::print()が呼び出されました. print関数の引数に派生クラスSuperの実態を差すBase型ポインタを与えたときに,Super::print()を呼び出せるようにするには,何か方法はありますか. p->print(p)の呼び出し部分をp->((Super*)p)にキャストしても結果は同じくBase::print()が呼ばれました. Base::print()の実装を無くした場合は,未解決の外部参照のコンパイルエラーが発生し, Base::print()を純粋仮想関数にした場合は,Super側でSuper::pirnt(Base*p)を実装しなければならないのか,抽象クラスのインスタンス化ができないというコンパイルエラーが発生します. これは,派生クラスとはいえ,引数リストの型が違うのでオーバーライドされていないということですよね. 引数をBase *p,Super *pからそれぞれvoid *pへ変更し,Super::print()内で(Super *)へキャストしなおしたところ,きちんとオーバーライドされ,うまくはいきました. しかしながら,この方法だと派生クラス側で実装する際に毎回キャスト処理を書かなくてはなりません. 他に何かきれいな方法はないでしょうか.

  • この2つのプログラムは全く同じものでしょうか?

    class Base{ protected int x; Base() { this.x=0;} Base(int x) {this.x=x;} void print(){ System.out.println("Base.x="+x);} } class Derived extends Base{ int x; Derived(int x1,int x2){ super(x1); this.x=x2;} void print(){ super.print(); System.out.println("Derived.x="+x);} } public class SuperTester{ public static void main(String[] args){ Base a =new Base(10); System.out.println("----a----"); a.print(); Derived b=new Derived(20,30); System.out.println("----b----"); b.print(); } } このプログラムと、 このプログラムのDerivedクラスのコンストラクタの部分を Derived(int x1,int x2){ super.x=x1; this.x=x2;} に変えたプログラムです。 かなりややこしいのですが、この2つのプログラムはソースは一部違いますが、 意味するものは全く同じでしょうか? ちなみにこの2つは実行結果は同じになります。 【実行結果】 ----a---- Base.x=10 ----b---- Base.x=20 Derived.x=30 つまり、Derivedクラスでint x;を書かず、 よろしくお願いします。

    • ベストアンサー
    • Java
  • 親クラスとオーバーライドらへんのこと

    はじめまして、最近c++をはじめたものです。 質問があります。 サブクラスで親クラスのメソッドをオーバーライドした時に、 そのメソッドの中で親クラスのメソッド(オーバーライドした)をメソッドを呼び出したいのですが。 やりかたがわかりません。 要するに、javaでいうsuperを使いたいのですが。。 コードで書くとこんなかんじです。 class base { public: int abc(); } class derived : public base { public: int abc(); } int derived::abc() { super.abc() //←ここの部分がわかりません。 他の処理 }

  • キャストによるアドレス変更について

    多重継承クラスのインスタンスのポインタを基底クラスのポインタ に代入するとき、キャストで、vtableへのポインタを変更するために、 多重継承クラスのインスタンスのポインタのアドレスから4byte加算 したアドレスが、基底クラスのポインタに代入されます。 以下のプログラムは、多重継承ではないですが、pCのポインタの アドレスに4byte加算してpAに代入されます。pAのデストラク タはvirtual宣言していないので、pAが指すアドレスにはvtable のポインタはないはずですが、4byte加算するという動作が起こるのは 何故でしょうか。 #include <iostream.h> class AAA { public: AAA(){} ~AAA(){} }; class BBB:public AAA { public: BBB(){} virtual ~BBB(){} }; class CCC:public BBB { public: CCC(){} ~CCC(){} }; int main(void) { CCC *pC = new CCC(); AAA *pA = (AAA *)(pC); delete pA; return 0; }

  • C++基底クラスに戻り値の異なる関数が宣言されている場合

    こんにちは。 質問させてください。 以下のようなコードがあったとします。 class Base1 { public:   virtual int get()=0; }; class Base2 { public:   virtual float get()=0; }; class Ex : public Base1, public Base2 { public:   int get(){return 0;}   float get(){return 0.0f;} }; void main() { } このプログラムをコンパイルすると 「'Ex::get': オーバーライドする仮想関数の戻り値の型が異なり、'Base1::get' の covariant ではありません。」 というエラーが出てしまいます。 関数の名前と引数が同じで戻り値だけが異なる場合はエラーが出るのはわかるのですが、基底クラスのBase1、Base2は変更不可能だとするとどのように回避すればいいのでしょうか? よろしくお願いします。 /*   WindowsXP Professional SP3   VisualStudio2005 AcademicEdition */

  • 派生クラスのメンバを基底クラスの参照に代入(C++

    文末のコードのように、 基底クラスで、派生クラスのメンバの参照を持つのはまずいでしょうか。 (classではなくstructにしているのは質問上でのpublic:の省略のためだけです) 初期化順序的には、基底クラスの参照先は、 基底クラスのコンストラクタが走る時点で初期化されていないので、 コンストラクタ内で参照に対して何かしようとすると問題になると思っています。 基底クラスのコンストラクタ内で派生クラスメンバの参照に対して何かしなければ、 参照は有効で、派生クラスのコンストラクタ実行後であれば 問題なく動くと思ってよいでしょうか。 struct A { int& m_ref; A(int& ref) : m_ref(ref) { } }; struct B : public A { int m_obj; B() : A(m_obj) { } };

  • ポインタのキャストについて

    下記のようなクラス定義があるとします。 説明のため、関係のない要素は省略し簡略化しています。 class HOGE { int a; char c; LPSTR lpszStr; // メンバ関数定義 } class HOGE_Derived : public HOGE { LPSTR _lpszStr; HOGE_Derived& operator= (HOGE& obj_HOGE); HOGE_Derived& operator= (HOGE_Derived& obj_HOGE_Derived); // メンバ関数定義 } このとき、下記のようなコードで演算子のオーバーロードを行っていますが、これは正しいのでしょうか? HOGE_Derived& HOGE_Derived::operator= (HOGE& obj_HOGE) { memcpy((HOGE*)this, &obj_HOGE_Derived, sizeof(HOGE)); lpszStr = NULL; // lpszStrのディープコピー _lpszStr = new char[strlen(obj_HOGE.lpszStr) + 1]; strcpy(_lpszStr, obj_HOGE.lpszStr); lpszStr = _lpszStr; return *this; } HOGE_Derived& HOGE_Derived::operator= (HOGE_Derived& obj_HOGE_Derived) { memcpy((HOGE*)this, (HOGE*)&obj_HOGE_Derived, sizeof(HOGE)); lpszStr = NULL; // lpszStrのディープコピー _lpszStr = new char[strlen(obj_HOGE_Derived.lpszStr) + 1]; strcpy(_lpszStr, obj_HOGE_Derived.lpszStr); lpszStr = _lpszStr; return *this; } 期待した動作は、まず最初のmemcpyで、obj_HOGEまたはobj_HOGE_Derivedオブジェクトのうち、基本クラス(HOGE)に存在するフィールドint aとchar cのみをコピーしたいのです。 memcpyによってこのようなコピーを行った時、処理系に依存せず期待した通りコピーできるものなのでしょうか? そもそも、このようなコピーの仕方自体、自然なやり方でしょうか? 気になるのは、HOGE_Derivedクラスのオブジェクトのメモリ内のデータの並びがどのようになっているのかと言うことです。 HOGE_Derivedクラスのポインタを、その基本クラスであるHOGE型にキャストした時に、このポインタで見えるエリアが、HOGE_Derivedクラスの中のHOGEクラスの部分だけと言うことは分かっているのですが、その部分のメモリ上の並びが必ず基本クラスの各フィールド→派生クラスで定義されたフィールドの順になっているのかどうか分かりません。 よろしくお願いします。

  • キャストの仕方がわかりません

    キャストの仕方がわかりません メソッド内でクラスを生成し、 そのクラスで共通処理を行いたいのですが、上手くいきません。 ジェネリクスの使い方が悪いのか、キャストで怒られてしまいます。 お分かりの方、いらっしゃいましたら教授願えますか。 以下、ソースです。 interface ToolInterface { /** 結果 */ public abstract Object toolResult(); } class TestA implements ToolInterface{ @Override public Object toolResult() { return "Aです"; } } class TestB implements ToolInterface{ @Override public Object toolResult() { return "Bです"; } } public class TestMain { public static void main(String args[]) { TestMain me = new TestMain(); me.dispResult(TestA.class); me.dispResult(TestB.class); } /** このメソッドでインスタンス化及び処理を行う */ private void dispResult(Class<?> obj) { try { obj.newInstance(); //ここでキャストか何かして表示させたい ToolInterface resObj = (ToolInterface) obj; System.out.println(resObj.toolResult()); } catch (InstantiationException e) { } catch (IllegalAccessException e) { } } }

    • ベストアンサー
    • Java
  • C#でクラス継承について

    下記のようなコードは、可能なのでしょうか? // クラス定義 abstract class Base { int a; Public int A { get{ return a; } } } class Sub1 : Base { int b; public int B { set { b = value; } } }; class Sub2 : Base { // 中略 } static class Program { [STAThread] static void Main(string [] args) { Base aaa = new Sub1(); Base bbb = new Sub2(); func(aaa); // ここでCS1502, CS1503 func(bbb); // ここでCS1502, CS1503 } void func(Sub1 _aaa) { // 中略 } void func(Sub2 _bbb) { // 中略 } } コメントに書いたとおり、CS1502(引数が合わない)が出ます。 func((Sub1)aaa); の様にキャストしないと、動作させることは難しいでしょうか? ※ 実際のコードでは、func(aaa), func(bbb)の呼び出し部分をループでまわしたいと考えています。