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

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

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

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

Q&A

解決済

1回答

1493閲覧

基底クラスからのdynamic_castがなぜか失敗する

HihuSnow

総合スコア23

C++

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

0グッド

0クリップ

投稿2019/07/15 09:33

以下のようにToken及びIntegerTokenを定義し

c++

1 2class Token { 3public: 4 5 Token(const Location _location, const TokenType _type); 6 virtual ~Token() {} 7 8 9 ig::token::Location location; 10 11 ig::token::TokenType type; 12 13}; 14 15/// Int型のリテラルを表します。 16class IntegerToken: public Token { 17public: 18 19 int value; 20 21 IntegerToken(const Location _location, const int _value); 22}; 23 24// 実装は省略(ただの変数割り当てです。)

vectorに入れると型情報が消えるので、
それをこのようにダウンキャストしようとしました。

c++

1let value = 120; 2let itoken = ig::token::IntegerToken({0, 0}, value); 3 4var vector = std::vector<ig::token::Token>(); 5vector.push_back(itoken); 6 7let _pitoken = dynamic_cast<ig::token::IntegerToken*>(&vector[0]); 8print(_pitoken->value); 9

なぜか、これでdynamic_castに失敗し、nulptrが帰ってきます。
どうしてでしょうか...?

let var printはそれぞれ、const auto auto cout...のマクロです。)

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

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

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

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

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

guest

回答1

0

ベストアンサー

C++

1ig::token::IntegerToken itoken = ig::token::IntegerToken({ 0, 0 }, 200); 2ig::token::Token token = itoken; 3ig::token::IntegerToken *pitoken = dynamic_cast<ig::token::IntegerToken*>(&token);

とした場合にnullptrが返るのと同じです。

std::vector<ig::token::Token>に入れてしまっているのでToken部分のみが格納され、IntegerTokenではなくなっています。

投稿2019/07/15 09:47

編集2019/07/15 10:14
SHOMI

総合スコア4079

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

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

HihuSnow

2019/07/15 10:13 編集

なるほど!C++では、Vectorに入れる(基底クラスにキャストする)と型情報が欠落するだけではなく、値そのものが消えるんですね! ポインタの配列にすれば良さそうかな? ありがとうございます!
HihuSnow

2019/07/15 11:17

```c++ let value = 120; let itoken = new ig::token::IntegerToken({0, 0}, value); var vector = std::vector<ig::token::Token*>(); vector.push_back(itoken); let _pitoken = dynamic_cast<ig::token::IntegerToken*>(vector[0]); print(_pitoken->value); ``` 解決した方法
yohhoy

2019/07/16 01:50

FYI: ここでは「スライシング(slicing)」が起きており、本来の型情報が欠落というよりも、意図せずig::token::Token型オブジェクトが生成されています。 https://teratail.com/questions/105052
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問