2017-08-12 9 views
0

私はオブジェクト指向アプローチとC++プログラミングの初心者です。 私の質問は、どのようなオブジェクトをインスタンス化していないクラスポインタが、そのクラス。以下、私は今日の下インスタンスを作成せずに非静的メンバー関数を呼び出す

#include <iostream> 


class Base{ 
public: 
    Base(){ 
      std::cout << "Base C-tor is called " << std::endl; 
    } 
    void fun(){ 
      std::cout << "Base fun() is called " << std::endl; 
    } 
    void sorrow(){ 
      std::cout << "Base Sorrow is called " << std::endl; 
    } 
    ~Base(){ 
      std::cout << "Base D-tor is called " << std::endl; 
    } 
}; 


int main(){ 

Base *b1; 
b1->fun(); 
b1->sorrow(); 
} 

をしようとした作業コードは、コードのこの部分の出力です:

Base fun() is called 
Base Sorrow is called 
+3

これは未定義の動作で、_workingコードではありません。 – user0042

+0

オブジェクト内のデータメンバーに決してアクセスしない関数は、静的でなければなりません。また、あなたが示すデザインが有用かどうかは疑問です。 Cのような関数を記述してクラスを追加することは、オブジェクト指向のプログラミングではありません。初期化されていないポインタへのアクセスは、未定義の動作です。コンパイラが未使用のポインタを最適化することは、あなたが有効なコードを書いたことを意味するものではありません。 – Klaus

答えて

2

未定義の動作を起動するにもかかわらず、あなたのコードは方法のための作業の外観を与えますコンパイラは非仮想メンバ関数を呼び出します。 fun()sorrow()メンバ関数の場合、インスタンスへのアクセスは実行されないので、関数は(呼び出しが無効のままであっても)機能しているかのように完了します。

あなたの機能virtualを宣言する場合(あなたは未定義の動作では何も保証することはできませんが)、クラッシュの可能性がかなり上がるでしょう:

virtual void fun(){ 
     std::cout << "Base fun() is called " << std::endl; 
} 
virtual void sorrow(){ 
     std::cout << "Base Sorrow is called " << std::endl; 
} 

仮想関数を呼び出すには、クラスのインスタンスにアクセスする必要が関数の場所を指定します。ポインタは初期化されていないので、コードはクラッシュする可能性が非常に高いです。

+0

答えをありがとう。はい、仮想では、クラッシュしました。オブジェクトへのアクセスに関しては、このクラスのプライベートメンバーであるfun()の変数の値を割り当てようとしました。私はそれに割り当てられた正しい値を印刷しました。 –

+0

@RahulSaraswatすべてのUBが同じように無効ですが、クラッシュを引き起こす可能性は異なります。一般に、関数呼び出しなどのCPU命令の実行に関係するものは、迷惑メモリの場所を読み書きするよりもクラッシュする可能性が高くなります(初期化されていないポインタを使用してプライベート変数にアクセスすると起こります)。 – dasblinkenlight

関連する問題