c++, MCVS 2012,头文件,矢量和命名空间

c++, MCVS 2012, header file, vector and namespaces

本文关键字:命名空间 MCVS 2012 c++ 文件      更新时间:2023-10-16

我很难找到我的问题(Q)的答案,所以我在这里注册,问你们它是如何真正工作的(或不工作);)

我在Visual Studio 2012中使用c++编写,但仍然不知道头文件中的#include,命名空间等是如何使用的。我真的需要用它们吗?

(Q1):假设我有一个。cpp文件和几个。h文件,它们正在使用,例如:向量,来自和其他一些库的东西,但我不写#include 在头文件中,只在。cpp中。对吗?或者我应该在每个标题中包含我使用的所有内容?

通常一切都为我工作,我甚至可以说它总是"工作",因为我还没有太多的经验,我通常包含一个。cpp和1或2头与一些void函数的一切。但不知道它是否工作,因为它应该,或者因为,例如,mu编译器允许这样做,在某些问题上,它可能会导致错误。

(Q2):关于使用命名空间std;在某些情况下,.h文件中的函数没有它也可以工作,但有时不是。例如,正在工作的空(只是用于合并排序的简单空):

#ifndef LISTA_1_H
#define LISTA_1_H
#include "Lista_0_Zadanie_1.h"
void MERGE(vector<double> &A, int p, int q, int r)
{
int i = p;
int j = q+1;
int lenght = r - p + 1;
int k=0;
vector<double> merged;
merged.assign (lenght,0);
while((i<=q)&&(j<=r))
    {   
    if(A[i] <= A[j])
        {
        merged[k]=A[i];
        ++i;
        }
    else
        {
        merged[k]=A[j];
        ++j;
        }
    k++;
    }
if(j<=r)
    {
    while(j<=r)
        {
        merged[k]=A[j];
        ++j;
        ++k;
        }
    }
if(i<=q)
    {
    while(i<=q)
        {
        merged[k]=A[i];
        ++i;
        ++k;
        }
    }
for (i=0;i<lenght;++i)
    A[p+i]=merged[i];
}

void MERGESORT(vector<double> &A, int k, int l) 
{
if(k<l)
    {
    int m = (k+l)/2;
    //int mp = m+1;
    //  cout << "koza"<<endl;
    MERGESORT(A,k,m);
    MERGESORT(A,m+1,l);
    MERGE(A,k,m,l);
    }
}
void TRIPLE_MERGESORT(vector<double> &A, int k, int l)  
{
if(k<l)
    {
    int one_third = (l-k)/3;
    int two_third = 2*(l-k)/3;          // k < k+one_third < k+two_third < l
    TRIPLE_MERGESORT(A,k,k+one_third);
    TRIPLE_MERGESORT(A,k+one_third+1,k+two_third);
    TRIPLE_MERGESORT(A,k+two_third+1,l);
    MERGE(A,k,k+one_third,k+two_third);
    MERGE(A,k,k+two_third,l);
    }
}
void INSERT_MERGESORT (vector<double> &A, int k, int l)
{
if(l<19)        // l=n-1, więc n<20 <=> l < 19
    {
    double y;
    int i,j;
    for(i=0; i<l+1; ++i)
        {
        y = A[i];
        j = i-1;
        while((j>=0) && (A[j]>y) )
            {
            A[j+1] = A[j];          
            --j;
            }
        A[j+1]=y;
        }
    }
else
    MERGESORT(A,k,l);
}
#endif

…在某些情况下,它不工作,如果我不写"使用命名空间std;"或在正确的位置添加"std::"(这里在vector之前),它不工作:

#ifndef SCHEMAT_HORNERA_H
#define SCHEMAT_HORNERA_H
//using namespace std;
 void HORNER( int n, double z0, double p_z0, vector<double> a, vector<double> &B)
{
B[n] = a[n];
for(int k = n-1; k>=0; --k)
    {
    B[k] = a[k] + z0*B[k+1];
    }   
}
#endif

我的问题是:我应该总是使用"std::"还是"using namespace std"?如果是,为什么我的文件到现在还在"工作"?因为在某些情况下VS允许,而它是不正确的和一些编译器,不允许这个?

Q1)您是否需要#include具有完整定义的头取决于您是否需要完整定义,或者如果只是前向声明就可以了。在只需要前向声明的情况下,您只需要告诉编译器某些东西的名称。一个例子是,如果你需要一个指向某物的指针:

// fw-decl Foo
class Foo;
// define Gizmo
class Gizmo
{
public:
  void DoIt();
  Foo* mFoo;  // just need a pointer, so don't need a full definition of foo
};

之后,如果您实际使用Foo对象,您将需要一个完整的定义,如:

#include "foo.h"
#include "gizmo.h"
void Foo::DoIt()
{
  mFoo->DoSomething(); // now we need a full definition
}

另一方面,如果编译器需要知道例如Foo有多大,那么你需要一个完整的定义。

#include "foo.h"
class Gizmo
{
public:
  Foo mFoo;  // need a full definition here
};

作为一般的经验法则,最好只在必要时提供完整的定义,以便使编译时间尽可能快。

Q2)简化的经验法则:从不使用using namespace std。如果您只是遵循这条经验法则而不考虑它,那么您将永远不会遇到名称空间冲突、污染全局名称空间或其他问题。

当然,对于那些真正以思考为生的人来说,这条经验法则有点过于简化了,所以这里有一个稍微好一点的:

1)不要在标题中使用using namespace2)永远不要在源文件中使用using namespace,除非它是你要实现的自己的命名空间。

经验法则可能会过于严格,这也不例外,但它会让你在前进的道路上不会冒险走得太远。using anmespace的问题是它将该名称空间中的任何内容带入全局范围。假设您有自己的头文件:

mystring.h

namespace MyString
{
    class string
    {
      // ...
    };
}

…然后在源文件中:

#include "mystring.h"
#include <string>
using namespace MyString;
using namespace std;
string s;  // OOPS:  which "string" is this?  MyString::string, or std::string?

这种歧义在这里很明显,但在现实世界中可能不那么明显,并导致一些非常难以检测的错误。

(1)记住include声明的实际作用是很重要的。基本上,它只不过是对新文件中包含的整个文件进行简单的复制/粘贴。

由于头文件包含在许多地方,所以通常不赞成在.h文件中包含许多不必要的内容(除非使用模板)。一般来说,当向前声明足够时,不要在头文件中包含。

在。cpp文件中,包括所有必要的文件,以便程序可以编译。

因为您使用的是visual studio,所以您必须小心,因为它对于包含您实际上忘记包含的标准库中的文件非常宽容,并且您可能会在其他系统上编译时遇到问题。

(Q2)在头文件中你不应该有"using"语句。请记住,include语句是一个简单的复制/粘贴;因此,如果你有一个using语句,它也会被包含在新文件中。

在。h文件中,你应该总是使用std::vector, std::set等。

在。cpp文件中,可以使用命名空间std,使用std::vector等。

(侧边栏)与您的代码相关,您应该将其拆分为头文件和cpp文件。在.h文件中没有定义,只有声明。创建一个.cpp文件并在其中定义算法。也不要在.cpp文件中定义守卫。永远不要包含.cpp文件!