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

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

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

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

Q&A

解決済

2回答

1048閲覧

【C++】 仮想関数の使いみち

torimingo

総合スコア122

C++

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

0グッド

0クリップ

投稿2019/03/27 23:19

編集2019/03/27 23:22

仮想関数というのは、newするときにアップキャスト(?)したときにだけ、効果が発揮されるものという認識は正しいでしょうか?
まずは、コードを示します。

c++

1#include <iostream> 2using namespace std; 3 4#define PRINT(X) (cout << X << endl) 5 6class Parent 7{ 8public: 9 // 関数 10 void sing() { PRINT("parent sing"); } 11 // 仮想関数 12 virtual void v_sing() { PRINT("parent v_sing"); } 13}; 14 15class Child : public Parent 16{ 17public: 18 // 関数をオーバーライド 19 void sing() { PRINT("child sing"); } 20 // 仮想関数をオーバーライド 21 virtual void v_sing() { PRINT("child v_sing"); } 22}; 23 24int main() 25{ 26 Parent parent; 27 parent.sing(); // 関数 28 parent.v_sing(); // 仮想関数 29 30 Child child; 31 child.sing(); // オーバーライドした関数 32 child.v_sing(); // オーバーライドした仮想関数 33 34 // アップキャスト(?)してnewする 35 Parent* p_child = new Child(); 36 // 以下はChildの関数が使われるかと思いきや、Parentの関数が使われる 37 p_child->sing(); // オーバーライドした関数 38 // 仮想関数であれば、Childのものが使われる 39 p_child->v_sing(); // オーバーライドした仮想関数 40 41 return 0; 42}

実行結果を以下に示します。

parent sing parent v_sing child sing child v_sing parent sing child v_sing

newするときに、アップキャスト(?)しない場合(実行結果の上から4行)、virtualを使っても使わなくても違いはないように思えます。
newするときに、アップキャスト(?)した場合(実行結果の下から2行)のみ、virtualを使う意味があるように思えます。

virtualは、アップキャスト(?)してnewしなければ意味がない、という認識は、正しいでしょうか?

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

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

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

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

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

guest

回答2

0

こんにちは。

newするときにアップキャスト(?)したときにだけ、効果が発揮される

もう解決しちゃってますが、ちょっと違います。

同じ継承ツリー内の他の型へキャストされたポインタ経由で呼び出しても、当該インスタンスを生成した時の型の関数が呼び出されます。
つまり、newして他の処理を行い、その後アップキャストするような場合でも有用です。

C++

1base* foo = new derived; 2foo->virtualFunction();

C++

1derived* foo= new derived; 2base* bar= nullptr; 3//・・・ 4bar = foo; 5bar->virtualFunction();

では、???->virtualFunction();で呼び出される関数は同じものです。

投稿2019/03/28 01:15

Chironian

総合スコア23272

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

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

torimingo

2019/03/28 02:03

ご回答頂き、ありがとうございます。 そのような使い方もできるのですね。 機会があったら、使わせて頂きます。
guest

0

ベストアンサー

正しいです。

と回答して、あなたになにか得られるものはあるでしょうか。
動作を理解するのもいいですが、なぜそういうことをするのか、それでなにが実現できるか、という
オブジェクト指向というものの方も理解するようにしましょう

投稿2019/03/27 23:30

編集2019/03/27 23:46
y_waiwai

総合スコア87749

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

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

torimingo

2019/03/28 00:00

ご回答を、ありがとうございました。 どのようなものが実現できるか、という観点にたって、virtualについて、もう一度考えてみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問