teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

追記

2017/04/04 08:48

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -1,5 +1,20 @@
1
- catsforepawさんとChironianさん回答を拝見して気づきました。
1
+ 追記2: 自分は適切な回答ができなかったのですが、他のみなさんのコメントを拝見して改めてC++でのオブジェクトの初期化メカニズムを確認してみました。
2
2
 
3
+ class 1 <- ... <- class i-1 <- class i <- class i+1 <- ... <- class N
4
+
5
+ のような継承関係があるクラスclass Nがあったとして、class Nのコンストラクションではコンストラクターの本体はclass 1 からclass Nまで、基底クラスから派生クラスの順番に起動されますが、class iのコンストラクターが実行中の状況ではclass 1 ~ class iまでの仮想関数の中からのみ起動関数が解決される仕様なんですね。
6
+
7
+ 自分がこれを勘違いしたのは他の言語からの不完全な類推からです。Javaなどではコンストラクター本体の起動順序はC++と同様基底から派生の方向です。またclass iのコンストラクター実行中に起動するメソッドがどれになるかもC++と同様class 1 ~ class iの中から解決されます。しかし抽象メソッド(C++でいう純粋仮想関数)の扱いが異なっていました。C++ではvirtual/非virtualいずれでも必ずclass 1~class iの中で起動すべきメンバー関数が決定できなければならないようです。それに対してJavaではclass 1~class iの中までで解決できないメソッド(class iで抽象メソッドになっているもの)は起動が許され、それはclass i+1~class Nまでの中で解決されることになっています。
8
+
9
+ 個人的な理解ですが、この仕様の違いはコンストラクターが起動される際のインスタンスの状態の違いによると思いました。C++ではclass iのコンストラクター本体の実行が開始する以前はそのインスタンスは「class iの**インスタンスではまったくない**」という思想であり、Javaはそれを若干ゆるくしており「必要に応じてclass iの**インスタンスとみなせる**」という思想だと思います。よって「class iのコンストラクターがclass 1~class iまでに実装がない抽象メソッドを呼び出すならば、それはclass iが派生クラスのメソッドを呼び出すことを明示的に意図していると解釈する」となっているのだと思います。
10
+
11
+ 質問者さんがやろうとしていることはオブジェクト指向をサポートした言語の中で「それを許している言語」と「それが制限されている言語」に分かれる手法でであり、C++ではそれが制限されていると言えると思います。
12
+
13
+ こうした違いはいろいろありそうなので各言語の思想に応じて頭を切り替えなければなりませんね…
14
+
15
+ ---
16
+ 追記1: catsforepawさんとChironianさんの回答を拝見して気づきました。
17
+
3
18
  自分の回答は抽象クラスのコンストラクターで純粋仮想関数を呼べないという点を指摘できていませんでした(できると思い込んでいました)。不適切な回答であったと思います。大変失礼しました。
4
19
 
5
20
  ---
@@ -22,4 +37,5 @@
22
37
 
23
38
  このようにするとobjはAbstractのインスタンスではなくインスタンスのアドレスを格納するポインター変数なのでこの変数を宣言しただけではAbstractクラスの実体が作られるということはありません。
24
39
 
25
- 代入文が実行される際に右辺が評価され、newによるConcreteのインスタンスが生成され、その先頭アドレスがobjに無事代入されるという意味・動きになります。
40
+ 代入文が実行される際に右辺が評価され、newによるConcreteのインスタンスが生成され、その先頭アドレスがobjに無事代入されるという意味・動きになります。
41
+

3

訂正

2017/04/04 08:48

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -1,4 +1,4 @@
1
- Chironianさんの回答を拝見して気づきました。
1
+ catsforepawさんとChironianさんの回答を拝見して気づきました。
2
2
 
3
3
  自分の回答は抽象クラスのコンストラクターで純粋仮想関数を呼べないという点を指摘できていませんでした(できると思い込んでいました)。不適切な回答であったと思います。大変失礼しました。
4
4
 

2

再度訂正

2017/04/04 02:37

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  Chironianさんの回答を拝見して気づきました。
2
2
 
3
- 自分の回答は抽象クラスのコンストラクターからvirtualを呼べないという点を指摘できていませんでした。不適切な回答であったと思います。大変失礼しました。
3
+ 自分の回答は抽象クラスのコンストラクターで純粋仮想関数を呼べないという点を指摘できていませんでした(できると思い込んでいました)。不適切な回答であったと思います。大変失礼しました。
4
4
 
5
5
  ---
6
6
 

1

訂正

2017/04/03 19:09

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -1,3 +1,9 @@
1
+ Chironianさんの回答を拝見して気づきました。
2
+
3
+ 自分の回答は抽象クラスのコンストラクターからvirtualを呼べないという点を指摘できていませんでした。不適切な回答であったと思います。大変失礼しました。
4
+
5
+ ---
6
+
1
7
  クラス定義はよいと思うのですが、mainの中の記述が問題です。
2
8
 
3
9
  Abstract obj;