ポインタについての質問があります。
1つ目に、型が違うポインタは、どう解釈されるんでしょうか??
C++
1char qtr = 3289; 2int * ptr = &qtr;
こんなコードがあったとします。
RISC系CPUならアライメントにまたがるため例外が送出されると思います。通常このような使い方はしないですよね。
int型のポインタにchar型のアドレスを代入しています。
この場合、ptrは、**int型のポインタと解釈されるのでしょうか?**それとも、char型のポインタでしょうか?
C++
1class Base {} 2class Derived : public Base {} 3 4Derived obj; 5Base *ptr = &obj;
こちらは、どうでしょうか?よく見かけるコードです。ptrは、結局のところどちらのポインタだと解釈されるんでしょうか??
2つ目
dynamic_castがわかりません。
私の持っている本に以下のような事が書いてあります。
ポインターやリファレンスの指し示しているオブジェクトの本当のクラス型は、実行時にしか分からない。
え?なんで??
上記のコードの例だと、ptrに、Derived型のオブジェクトが入っていることは、実行しなくてもわかりますよね??
C++
1void f(Base & base){ 2 Derived & d = static_cast<Derived &>(base); // baseがderivedを参照しているかどうかは、わからない。 3}
関数内では、確かに、参照しているかどうかは不明です。
ですが・・・f関数を呼び出した時に渡すオブジェクトは、実行時でなくてもわかりますよね?
ポインターやリファレンスの指し示しているオブジェクトの本当のクラス型は、実行時にしか分からない。そのため、常に変換に失敗する可能性がある。そのため、dynamic_castを使う場合は、常に変換が失敗するかもしれないという前提のもとにコードを書かななければならない。
ん??一体なんのことだかサッパリ。
3つ目にダウンキャストはなぜ危険なのでしょうか??
基本型のポインターを派生型のポインターに変換する
線形リストなどを作る時に、自己参照型のポインタって良く見ますよね。
C++
1typedef struct __node { 2 int data; 3 struct *__node next; 4}Node;
これは、ポインタが不完全型であっても使用可能だからですよね。
この理由は、ポインタは、アドレスを代入するものであって、構造体の中身がどうなっていようが、アドレスの値に影響しないからだと考えました。(間違っているかもしれません。)
この理屈で考えてみます。テスト用のコードを作りました。適当です。
以下のコードは、コンパイルは通ります。しかし、コンパイルする際にNever Succeedと出てきます。
なぜでしょうか??
C++
1struct Base { 2 int member = 3489; 3 4 void function(){ 5 std::cout << "Base::funtion" << std::endl; 6 } 7 8 virtual void func(){ 9 std::cout << "Base::virtual_func" << std::endl; 10 } 11}; 12 13class Derived final : public Base { 14 public: 15 int Derived_member = 3829; 16 17 void function(){ 18 std::cout << "Derived::function" << std::endl; 19 } 20 21 void func(){ 22 std::cout << "Derived::virtual_func" << std::endl; 23 } 24}; 25 26 27Base base_obj; 28Derived *derived_obj_ptr = dynamic_cast<Derived *>(&base_obj);
以下のコードを見てみます。
基本クラスのオブジェクトを派生クラスのオブジェクトに代入することは可能です。
しかし、逆に、派生クラスのオブジェクトを基本クラスのオブジェクトに代入することはできません。
これは、派生クラスには、基本クラスにないメンバ変数を持っている可能性があるから、コピーのしようがない・・・ということでしょう。
(この時に使われるのは・・・コピー代入演算子ですかね?基本クラスのオブジェクトが右辺に来ている・・・時は、どうなんでしょうか?)
C++
1class Base { ... }; 2class Derived : public Base { ... }; 3 4Base obj; 5Derived obj2; 6 7obj2 = obj; // ok! 8obj = obj2 // ERROR!!
オブジェクトの方は分かるのですが、ポインタの方はなぜできないのかわかりません。
また、ダウンキャストができる条件を教えてください。
環境は、Linux g++です。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/28 02:02
2018/08/28 02:05
2018/08/28 02:10
2018/08/28 02:13
2018/08/28 02:19
2018/08/28 02:26
2018/08/28 02:40
2018/08/28 04:23
2018/08/28 04:27
2018/08/28 06:38
2018/08/28 06:42
2018/08/28 08:26