忍者ブログ

神戸電子専門学校ゲームソフト学科の生徒が運営するGESのブログです。

   

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

C++erならnullptr使おうよ!! 2年3年向け



どうもuncleです。

今回はこちらで紹介されているnullptrがC++11で実際に実装されているので情報の更新?をさせてもらいます。


拍手[0回]




まずnullptrが何なのかと言うとNULLのC++版とでも理解してもらえればいいかと思います

NULLは皆さんお馴染みのポインタの初期化で一般的に使われるマクロですね
中身は「stdio.h」や「stdlib.h」に定義されています。

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else  /* __cplusplus */
#define NULL    ((void *)0)
#endif  /* __cplusplus */
#endif  /* NULL */


#ifdef / #ifndef / #elseと言うのはディレクティブと言って#includeや#defineの様なコンパイルの前(
プリプロセッシング)の段階で行われる特別な処理の1つです
気になった人はプラグマディレクティブなども一緒に調べてみると幸せになれるかもしれません

余計な話はこのぐらいにして本題に戻ります。
ここにはC言語の場合はNULLを((void*)0)と定義
C++言語の場合にはNULLを0と定義すると書いてあります


Cの場合は0をvoid*型にキャストすることでNULLを定義しています
C++の場合は、0は特別な値として扱われ任意の型のポインタ型に変換される事が保証されています

ですが

我々はC++erです。
C++erならC++erらしくC++を記述しましょうよ!
NULLとはおさらばです!!!

と言うことでnullptrの魅力を余すこと無くご紹介します

メリットその①
インクルードが必要ない!
先程も言いましたがNULLはマクロですのでインクルードが必要になります
ですがこのnullptrはintなどと同様にキーワードとして定義されているので、いつでも使用することが出来ます!!

メリットその②
改変される可能性が無い!!
どういう事かと言うと先程も説明したディレクティブの1つに#undefというものがあり、#defineして定義した内容を無効化するというものがあります。
簡単なサンプルを書いてみると

// Main.cpp内--------
------------------------------------------------

#include <stdio.h>
#include "Test.hpp"

// NULLの定義を無効化しNULLを再定義する
#undef NULL
#define NULL ((int*)0xDEADC0DE)

int main( void )
{
      int* pInteger = NULL;
      Func( pInteger );
      return 0;
}

// Test.hpp------------
-----------------------------------------------

#include <stdio.h>

void Func( int* _p )
{
     
// Test.hpp内でのNULLの定義は0
      if( _p == NULL )
      {
            // 何かの処理~~
      }
      return;
}

このようなプログラムがあった場合にFuncのif文に入ることはありません。
まぁこんなプログラムを書く人は居ないとは思うんですが・・・・。
でもこう言う改変が可能であるって言うのはちょっと怖いですよね
でもnullptrはキーワードとして定義されているため改変することは出来ません
nullptrさんって素敵!!抱いて!!!


メリットその③
C++の0はあくまでも整数として扱われる!!!
先ほどC++では0は任意のポインタ型に変換されると書いたのですが0はあくまでも整数型です
その付加機能として任意のポインタ型に変換されると言う機能を持っているのでこのような場合に問題が発生します。

#include <stdio.h>

void Func( int _Test )
{
    printf( "整数型です\n" );
}

void Func( int* _pTest )
{
    printf( "ポインタ型です\n" );
}

int main( void )
{
    Func( NULL );
    return 0;
}

ポインタ型として渡しているつもりでこのコードを書いた場合・・・
残念ですがint 型を引数に持つFunc関数がコールされます。
Funcの引数としてnullptrを渡した場合には勿論int* を引数に持つFunc関数がコールされます。



と言うことで・・・・
C++erならnullptrを使いやがれ!!!!

以上!!





追記!
ここからは読まなくても大丈夫!

今回紹介したnullptrは実際にはstd::nullptr_t型として定義されています。
これはstddef.h内で確認することが出来ます。
ここは本題から話がそれてしまうので割愛させてもらいます。
ここでちょっと補足として話しておきたいことはnullptrはポインタ型ではなくstd::nullptr_t型であるということです。

メリット③で紹介したソースに
void Func( nullptr_t _Null )
{
      printf( "nullptrです\n" );
}
と言うソースを追加した場合この関数が呼ばれることになります。

まぁ普段nullptr_t型を使うことはないと思うので大きな問題では無いんですが一応補足ということで

後はcstddefを探している時に恐らくandroid用のC++で互換性を保つためのnullptrの定義が書いてあるcstddefを見つけました
ソースはこちらから確認することが出来ます
実際の定義とは違うんですがnullptrとしての要件は満たしているので参考になるかと思います。



では改めて・・・

以上!!!!!



PR

COMMENT

NAME
TITLE
MAIL(非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS(コメント編集に必須です)
SECRET
管理人のみ閲覧できます

ブログ内検索

最新コメント

[01/29 人面犬]
[10/01 8ch]
[09/12 uncle]
[09/10 某卒業生]
[06/07 uncle]

カレンダー

10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

テスト

Copyright ©  -- GESブログ --  All Rights Reserved
Design by CriCri / Photo by Geralt / powered by NINJA TOOLS / 忍者ブログ / [PR]