コードの再定義

入門

    再定義は、一言で言えば2回以上定義された同じ変数です。次のコードに示すように、クラスにTEST.Hで定義された、私はadd.hとmain.cppにでTEST.Hファイルを引用してきたように、コンパイルのプロセスのこの時間は、エラーを生成します。

テストコード

/*****test.h*****/
class Test{
public:
    int i;
};
/*****add.h*****/
#include "test.h"

int Add1(int a,int b);
/*****add.cpp*****/
#include <iostream>
#include "add.h"

int Add1(int a, int b)
{
  Test test_add;
  std::cout<<"This Add1 function"<<std::endl;
  return a+b;
}
/*****main.cpp*****/
#include <iostream>

#include "add.h"
#include "test.h"

int main()
{
  Test test_main;
  std::cout<<"Run main"<<std::endl;
  std::cout<<"1+1="<<Add1(1,1)<<std::endl;
  return 0;
}

どのように回避するために、

1. #ifndefの

    #ifndefの使用中に、マクロコマンドは、この問題を回避するために使用することができる次のように、使用することです。

#ifndef MY_TEST_TEST_H
#define MY_TEST_TEST_H
class Test{
public:
    int i;
};
#endif //MY_TEST_TEST_H

    この条件コンパイルIFNDEF同じCPPファイルを防ぐためである以上、同じ.Hよりも(例えばmain.cppにファイルとしてメイン文書はときに、TEST.H、add.hが含まれていますが、またTEST.Hが含まれて含まれていますコンパイル時にコンパイラがCPPファイルに従って、ユニット、各CPPファイルとしてコンパイルされているため、.CPP引用の追加機能は、#include <TEST.H>、(理由は上記の条件でエラーなしでコンパイルされている)になるとき.oファイルをコンパイルして、一緒に.oファイルをそれらをリンクし、最終的には次の2つのcppファイル内の.hファイルに含まれているランタイムのリンクを持つ実行可能ファイルを形成する。これは、基本的かつ条件付きコンパイルで問題ではない。あなたはそれは次の2つのcppファイルを意味してTestクラスの.hファイルで定義され、それぞれのcppファイルには、グローバル変数の定義:.クラスのテストを持っています。際、もちろん、別々にコンパイルごとのcppファイル、問題はないが、ときに2つのcppのファイル変数のテストクラスを持っているので、当然のことながら、定義ああ、問題を繰り返すことで、時間にリンクされている:問題が生じるが、リンクアップ
    条件付きコンパイルの使用は、この問題を解決することができますが、しかし、テキスト付き 部品は、この時間が問題に条件付きコンパイルの故障の原因となります、繰り返されることが明らかに増加マクロにつながる。そして、毎回重複した定義があるかどうかを決定するために、ヘッダファイルを開くには、コンパイラの必要性を、それほど大規模なプロジェクトをコンパイルするときに、意志IFNDEF#することができます比較的長い、これやり方一度いくつかのコンパイラのに#pragmaをサポートするために、それ以降コンパイル時。

2.使用に#pragma一度

    次のようにこの問題を回避するために、マクロ一度使用の#pragma中に使用することができ、使用は次のとおりです。

#pragma once
class Test{
public:
    int i;
};

    あなたは、だけファイルの、ヘッダファイル内のコードの一部に声明一度に#pragmaをすることはできません。利点は、あなたが、マクロ名の競合を心配する必要はありませんもちろん、紛争によって誘発される奇妙なマクロ名が表示されないということです。したがって、コンパイル速度の大規模プロジェクトとは少し改善します。クロスプラットフォームは、いくつかのプラットフォームでは、この使用をサポートしていない場合は、今、私が遭遇していません。

3.匿名の名前空間を使用して(拡大)

    次のように使用します。

namespace {
  class Test{
  public:
    int i;
  };
}

    コンパイラは、この名前空間の内部の一意の名前を生成するだけでなく、匿名の名前空間のusingディレクティブを生成します。だから、実際には上記のコードは同等です:

     namespace __UNIQUE_NAME_ {
         class Test{
         public:
             int i;
         };
     }
     using namespace __UNIQUE_NAME_;

    使用は、変数の匿名のスペースの再定義をも防止することができるのはなぜ匿名のスペースがスコープが現在のファイルの名前に制限されていることを、リンク属性と静的グローバル名が同じであると宣言されている内部リンク属性を持っているので、あなたがすることはできません別のファイルで宣言にexternを使用してリンクします。あなたが名前の使用が世界的な静的な内部リンクの属性を宣言している促進しない場合は、匿名の名前空間は、より良い同じ効果を達成するための方法として使用することができます。

リンク属性の三種類(拡大)

内部(内部)の外部(外部)、なし(なし) - 三種類に分けリンク属性(リンク)。

外部属性:外部リンクの属性手段は、識別子は、現在のソースファイルで、ファイルが他のプログラムで使用できるだけでなく使用することができます。
内部属性:使用が変更され、静的な識別子は、ソースファイル内の有効な内部リンケージプロパティがあります。constが内部リンクを修正はextern constの、財産以上にextern const属性の圧力があった場合、プロパティは外部リンクとなり、また、デフォルトの属性です。
なし属性:ローカル変数。

反射

    なぜ、この記事を書きます。実際に変数が再定義されているので、これはあり、中TEST.Hでのconstのchar * strの=「テスト」の使用;ヘッダファイルが、効果なしで、私が使用した後、私はの#pragmaを使用していました我々は問題を解決することができます前に、匿名のスペース。これはなぜでしょうか?
    ヘッダファイルは、一般的に宣言変数に格納され、定義された変数が保存されるべきではありません。そして私は、変数の定義は保存し、複数のファイルの参照は、まだ迷っ問題、加えて、このような問題があるだろうに一度の#pragma、それは意味がありませんエラーが発生します!あなたがこの記事を読んでいる場合は、constのを聞いてきます内部リンクの属性を変更した上で言った、私はCONST文字を使用し、なぜエラーでしょうか?
    CONST変数は間違いなく、その後、内部リンクの属性を変更されていません。間違った理由私はのconst char型を使用しているためである
ので、ここでのcharではなく、ポインタ変数strの、STRであることはグローバルでのconstこの時点では変更され、。constポインタ変数がp型(CHAR変更された場合のconst strのを)私が遭遇した問題はのconst char型も話すことができますので、この時間外strのリンクが表示されていない文字に* constのか、constのはstd ::文字列(この時間std ::文字列ビット行き過ぎ)を使用して、

参考リンク

匿名スペース:https://www.cnblogs.com/youxin/p/4308364.html
リンクプロパティ:https://blog.csdn.net/u011285208/article/details/94738969
のconst内部リンクプロパティ:HTTPS:// WWW .cnblogs.com / sheshiji / P / 3427896.html

おすすめ

転載: www.cnblogs.com/SmallBlackEgg/p/12522173.html