2016-03-31 15 views
24
#include<iostream> 
using namespace std; 

class A { 
    public: 
    void f(){cout<<"A"<<endl;} 
}; 

class B : private A { 
    public: 
    void f(){cout<<"B"<<endl;} 
}; 

int main(){ 

としてクラスBが私的にクラスAを継承している、このアップキャストが動作するようになっていません。明示的な型キャスティングでプライベート継承のアップキャストが許可されるのはなぜですか?

A* a = new B; 

しかし、明示的な型キャストがそれを許可されています。 なぜですか?

A* a1 = (A*)new B; 
    a1->f(); 
    return 0; 
} 
+1

c-castはほとんどの変換を可能にします( 'int *'から 'A *'への変換も可能です)。使用法は、期待される出力を持つUBかもしれません。 – Jarod42

+0

重複:http://stackoverflow.com/questions/17925124/can-i-cast-a-derived-class-to-a-private-base-class-c –

答えて

18

A* a1 = (A*)new B; 

でのキャストはアクセスできないベースクラスへのキャストです。

これはCスタイルのキャストとしてしか表現できません。この状況でstatic_castを使用できる場合は、static_castの場合と同じで、reinterpret_castと等価ではありません。特に、結果アドレスは引数アドレスと必ずしも同じではありません。

C++ 11§5.4/ 4:

The same semantic restrictions and behaviors [as for a static_cast ] apply [for a C style cast], with the exception that in performing a static_cast in the following situations the conversion is valid even if the base class is inaccessible:

— a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicitly converted to a pointer or reference to an unambiguous base class type, respectively;

+2

reinterpret_castとconst_castの観点から表現すると、それはまったく有効なキャストではありません。 –

+5

@RichardHodges:アクセスできない基底クラスへのキャスト、および 'dynamic_cast'、そして一般的な場合の' static_cast'さえも 'reinterpret_cast'と' const_cast'で表現することはできません。私。 「reinterpret_castとconst_castの観点から表現できない場合、それはまったく有効なキャストではありません」という文章は、ナンセンスの主張です。ごめんなさい。 –

+1

私は参照を参照し、修正されています。ありがとうございました。 –

5

明示的なキャスティングでは、必要なすべてを行うことができます。たとえば、次のように書くことができます。

int *p = (int*)new B; 

このコードはコンパイルされます。 明示的なキャストとは、自分が行っていることを知っていることを意味します。

+12

*明示的なキャストは、あなたが何をしているかを知っていることを意味します。* =>通常は反対です。 :-) – HostileFork

+0

^^絶対にこれ!!! –

+0

明示的なキャストはコンパイラに "私がやっていることを知っている"と伝えます –

8

これは、Cスタイルのルールによって許可されているキャスト:あなたはstatic_castに変更すると

(N3337) [expr.cast]/4 : The conversions performed by

  • a const_cast (5.2.11),
  • a static_cast (5.2.9),
  • a static_cast followed by a const_cast,
  • a reinterpret_cast (5.2.10), or
  • a reinterpret_cast followed by a const_cast,

can be performed using the cast notation of explicit type conversion. The same semantic restrictions and behaviors apply, with the exception that in performing a static_cast in the following situations the conversion is valid even if the base class is inaccessible:

  • a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicit converted to a pointer or reference to an unambiguous base class type, respectively;

  • [...]

、これは失敗しますコンパイルします。 GCCは次のエラーを返します。

error: 'A' is an inaccessible base of 'B' 
    A* a1 = static_cast<A*>(new B); 
1

明示的な型キャストはオブジェクト指向の機能や規則を持たないC言語のプログラミング機能です。 C言語の場合は、すべてがポインタ(メモリまたは関数)です。 Updcastingとdowncastingは、C++によって提供されるオブジェクト指向の機能です。継承キャスティングは、言語のオブジェクトの向きの規則で動作する必要があります。しかし、このようなオブジェクトを型キャストすることによって、 は、構造体のポインタを別のものに強制することによって、オブジェクトをAとして扱うようコンパイラに強制します。したがって、コンパイラがキャストされたオブジェクトの呼び出しポインタf()に割り当てる関数ポインタを決定すると、Aクラスの実装のポインタが割り当てられます。

+0

オペアンプがなぜそれを尋ねるのか、これが最も関連性の高い答えだと思います。 –

関連する問題