这里写自定义目录标题

第一篇:解决方案、命名空间和项目的关系
一、解决方案、项目、程序集、命名空间
初学者很容易把这些概念搞混淆。先说说项目(Project),通俗的说,一个项目可以就是你开
发的一个软件。在.Net下,一个项目可以表现为多种类型,如控制台应用程序,Windows应用程
序,类库(Class Library),Web应用程序,Web Service,Windows控件等等。如果经过编译,
从扩展名来看,应用程序都会被编译为.exe文件,而其余的会被编译为.dl文件。既然是.exe文件,就
表明它是可以被执行的,表现在程序中,这些应用程序都有一个主程序入口点,即方法Main0。而类
库,Windows控件等,则没有这个入口点,所以也不能直接执行,而仅提供一些功能,给其他项目
调用。
在Visual Studio.Net中,可以在"File"菜单中,选择"new"一个"Project",来创建一个新的项
目。例如创建控制台应用程序。注意在此时,Visual Studio除了建立了一个控制台项目之外,该项目
同时还属于一个解决方案(Solution)。这个解决方案有什么用?如果你只需要开发一个Hello Worl
d的项目,解决方案自然毫无用处。但是,一个稍微复杂一点的软件,都需要很多模块来组成,为了体现彼此之间的层次关系,利于程序的复用,往往需要多个项目,每个项目实现不同的功能,最后将
这些项目组合起来,就形成了一个完整的解决方案。形象地说,解决方案就是一个容器,在这个容器
里,分成好多层,好多格,用来存放不同的项目。一个解决方案与项目是大于等于的关系。建立解决
方案后,会建立一个扩展名为.sln的文件。
在解决方案里添加项目,不能再用"new"的方法,而是要在"File"菜单中,选择“Add Project"。
添加的项目,可以是新项目,也可以是已经存在的项目。
程序集叫Assembly。学术的概念我不想提,通俗的角度来说,一个项目也就是一个程序集。从
设计的角度来说,也可以看成是一个完整的模块(Module),或者称为是包(Package)。因此,
一个程序集也可以体现为一个dll文件,或者exe文件。怎样划分程序集也是大有文章的,不过初学者
暂时不用考虑它。
命名空间(namespace)是在C++里面就有的概念。引入它,主要是为了避免一个项目中,可
能会存在的相同对象名的冲突。这个命名空间的定义,没有特殊的要求。不过基本上来说,为了保证
其唯一性,最好是用uri的格式,例如BruceZhang.com。这个命名空间有点像我们姓名中的姓,然
后每个对象的名字则是姓名中的名。如果有重复,再国外的命名中,还可以加上middle name。那
么名都为勇的,由于姓氏不同也就分开了,或者叫张勇,或者叫赵勇。当然人的姓氏重复者居多,所
以我们为命名空间取名时,尽可能的复杂一点。有许多初学者,常常把一个项目就理解为一个命名
空间。其实这两者没有绝对的联系,在项目里我们也可以定义很多不相同的命名空间。但为了用户便
于使用,最好在一个项目中,其命名空间最好是一体的层次结构。在Visual Studio里,我们可以在项
目中新建一个文件夹,默认情况下,该文件夹下对象的命名空间,应该是”项目的命名空间.文件夹
名”。当然,我们也可以在namespace中修改它。
命名空间和程序集名,都可以在Visual Studio中设置。用鼠标右键单击项目名,就可以弹出如下
对话框:
在图中,Assembly Name就是程序集名,如果经过编译,则为该项目的文件名。而Default Na
mespace则为默认的命名空间。在开发软件时,我们要养成良好的习惯,在建立新项目后,就将这些属性设置好。一旦设置好了Default Namespace,则以后新建的对象,其命名空间即为该设定的
值。至于程序集名,如果是dlI文件,建议其名最好与Default Namespace一致。
实例演练:
(一)创建控制台应用程序"Hello World!”
1、打开Visual Studio.Net,选择"File“菜单的"new",选择"Project";
2、选择Visual C#Projects中的"Console Application",如图所示:
在Location中,定位你要保存的项目的路径,而名字则为“FirstExample”。该名字此时既是解决
方案的名字,同时也是该项目的名字。
3、用鼠标右键单击项目名,在弹出的对话框中,将Assembly Name命名为HelloWorld,将De
fault Namespace命名为:BruceZhang.com.FirstExample。
4、此时Visual Studio中已经建立了一个文件,其名为Class1.cs(如果是Visual Studio 2005,
则默认为Program.cs);修改该文件的文件名为HelloWorld.cs,同时修改文件中的namespace,
和类名,如下:
namespace BruceZhang.com.FirstExample {///
/// Summary description for Class1.///
class HelloWorld {///
/// The main entry point for the application.///
[STAThread] static void Main(string[] args){// // TODO: Add code to start application here
//})}
5、注意在HelloWorld.cs中,有一个Main0方法。这是因为我们建立的是控制台应用程序。在
Main0方法中添加如下代码:
Console.WriteLine(“Hello World!”);Console.Read0;这里的Console是一个能对控制台进行
操作的类。
6、运行。
检查保存项目的路径文件夹FirstExample/bin/debug,已经存在了一个HelloWorld.exe文件。
(二)为解决方案添加一个新项目
1、在"File"菜单中,选择“Add Project",添加“New Project"。在对话框中选择"Class Librar
y”,名字为Printer。至于保存路径,可以放在之前建立的FirstExample文件夹下:
2、在Visual Studio右侧,可以看到现在有两个项目了。仍然修改新项目的名称和默认命名空间
名,均为BruceZhang.com.Printer。
3、将默认建立的Class1.cs改名为MessagePrinter.cs,同时修改其代码为:namespace Bruce
Zhang.com.Printer {///
/// Summary description for Class1.///
public class MessagePrinter { public MessagePrinter( {// // TODO: Add constructor logic he
re//}public static void Print(string msg){Console.WriteLine(msg);}}}在MessagePrinter类
中,我们注意到并没有Main0方法,因为它不是应用程序。新增加的Print0方法,能够接收一个字符
串,然后在控制台中显示出来。
4、编译Printer项目。鼠标右键单击该项目名,在菜单中选择"Build”。成功编译后,找到文件夹
Printer/bin/debug,可以发现有文件BruceZhang.com.Pridter.dll,这就是最后形成的程序集文
件。
5、关联这两个项目。我们希望是在FirstExample项目中用到Printer项目的Print0方法,前提是
需要在FirstExample项目中添加对Printer项目的引用。右键单击FirstExample项目的"Reference",
选择"Add Reference”,在对话框中选择“Project“标签,找到该项目并选中,最后如图所示:
6、现在就可以在FirstExample项目中使用MessagePrinter了。首先,在命名空间中添加对它的
使用(Using),然后再Main0方法中调用它,最后代码如下:
using System;
using BruceZhang.com.Printer; namespace BruceZhang.com.FirstExample {///
/// Summary description for Class1.///
class HelloWorld {///
///The main entry point for the application.///
[STAThread] static void Main(string[] args) { MessagePrinter.Print(“Hello World!”]; Console.R
ead0;}}}
7、运行。结果与前一个例子一样。
在这个例子中,解决方案中就包含了两个项目,一个是控制台应用程序,一个是类库。类库提供
一些基本的功能,如例子中的Print0方法。我们常常把一些共用的方法,放到类库中。这样其他的应
用程序就可以去调用它。例如本例的控制台应用程序。如果新建的Windows应用程序,也需要这个
功能,就可以直接引用MessagePrinter的Print0方法,而不必重复去实现。
第二篇:上传(图解)解决方案、项目、程序集、命名空间
解决方案、项目、程序集、命名空间
一、解决方案、项目、程序集、命名空间
初学者很容易把这些概念搞混淆。先说说项目(Project),通俗的说,一个项目可以就是你开
发的一个软件。在.Net下,一个项目可以表现为多种类型,如控制台应用程序,Windows应用程
序,类库(Class Library),Web应用程序,Web Service,Windows控件等等。如果经过编译,
从扩展名来看,应用程序都会被编译为.exe文件,而其余的会被编译为.dll文件。既然是.exe文件,就
表明它是可以被执行的,表现在程序中,这些应用程序都有一个主程序入口点,即方法Main0。而类
库,Windows控件等,则没有这个入口点,所以也不能直接执行,而仅提供一些功能,给其他项目
调用。
在Visual Studio.Net中,可以在"File“菜单中,选择"new“一个"Project”,来创建一个新的项
目。例如创建控制台应用程序。注意在此时,Visual Studio除了建立了一个控制台项目之外,该项目
同时还属于一个解决方案(Solution)。这个解决方案有什么用?如果你只需要开发一个Hello Worl
d的项目,解决方案自然毫无用处。但是,一个稍微复杂一点的软件,都需要很多模块来组成,为了
体现彼此之间的层次关系,利于程序的复用,往往需要多个项目,每个项目实现不同的功能,最后将
这些项目组合起来,就形成了一个完整的解决方案。形象地说,解决方案就是一个容器,在这个容器
里,分成好多层,好多格,用来存放不同的项目。一个解决方案与项目是大于等于的关系。建立解决
方案后,会建立一个扩展名为.sln的文件。
在解决方案里添加项目,不能再用"new"的方法,而是要在"File"菜单中,选择“Add Project"。
添加的项目,可以是新项目,也可以是已经存在的项目。程序集叫Assembly。学术的概念我不想
提,通俗的角度来说,一个项目也就是一个程序集。从设计的角度来说,也可以看成是一个完整的模
块(Module),或者称为是包(Package)。因此,一个程序集也可以体现为一个dlI文件,或者ex
e文件。怎样划分程序集也是大有文章的,不过初学者暂时不用考虑它。命名空间(namespace)
是在C++里面就有的概念。引入它,主要是为了避免一个项目中,可能会存在的相同对象名的冲突。
这个命名空间的定义,没有特殊的要求。不过基本上来说,为了保证其唯一性,最好是用uri的格
式,例如BruceZhang.com。这个命名空间有点像我们姓名中的姓,然后每个对象的名字则是姓名中
的名。如果有重复,再国外的命名中,还可以加上middle name。那么名都为勇的,由于姓氏不同
也就分开了,或者叫张勇,或者叫赵勇。当然人的姓氏重复者居多,所以我们为命名空间取名时,尽
可能的复杂一点。
有许多初学者,常常把一个项目就理解为一个命名空间。其实这两者没有绝对的联系,在项目里
我们也可以定义很多不相同的命名空间。但为了用户便于使用,最好在一个项目中,其命名空间最好
是一体的层次结构。在Visual Studio里,我们可以在项目中新建一个文件夹,默认情况下,该文件夹
下对象的命名空间,应该是“项目的命名空间.文件夹名”。当然,我们也可以在namespace中修改
它。命名空间和程序集名,都可以在Visual Studio中设置。用鼠标右键单击项目名,就可以弹出如
下对话框:
在图中,Assembly Name就是程序集名,如果经过编译,则为该项目的文件名。而Default Na
mespace则为默认的命名空间。在开发软件时,我们要养成良好的习惯,在建立新项目后,就将这些
属性设置好。一旦设置好了Default Namespace,则以后新建的对象,其命名空间即为该设定的
值。至于程序集名,如果是dlI文件,建议其名最好与Default Namespace一致。
实例演练:
(一)创建控制台应用程序”Hello World!”
1、 打开Visual Studio.Net, 选择"File"菜单的"new", 选择"Project";
2、选择Visual C#Projects中的"Console Application",如图所示:
在Location中,定位你要保存的项目的路径,而名字则为"FirstExample"。该名字此时既是解决
方案的名字,同时也是该项目的名字。
3、用鼠标右键单击项目名,在弹出的对话框中,将Assembly Name命名为HelloWorld,将De
fault Namespace命名为:BruceZhang.com.FirstExample。
4、此时Visual Studio中已经建立了一个文件,其名为Class1.cs(如果是Visual Studio 2005,
则默认为Program.cs);修改该文件的文件名为HelloWorld.cs,同时修改文件中的namespace,
和类名,如下:namespace BruceZhang.com.FirstExample{///
/// Summary description for Class1. ///
class HelloWorld {///
/// The main entry point for the application. ///
[STAThread] static void Main(string[] args) {// // TODO: Add code to start application here
//)})
5、注意在HelloWorld.cs中,有一个Main0方法。这是因为我们建立的是控制台应用程序。在
Main0方法中添加如下代码:Console.WriteLine(“Hello World!”);Console.Read0;这里的Consol
e是一个能对控制台进行操作的类。
6、运行。
检查保存项目的路径文件夹FirstExample/bin/debug,已经存在了一个HelloWorld.exe文件。
(二)为解决方案添加一个新项目
1、在“File"菜单中,选择"Add Project",添加"New Project"。在对话框中选择"Class Librar
y”,名字为Printer。至于保存路径,可以放在之前建立的FirstExample文件夹下:
2、在Visual Studio右侧,可以看到现在有两个项目了。仍然修改新项目的名称和默认命名空间
名,均为BruceZhang.com.Printer。
3、将默认建立的Class1.cs改名为MessagePrinter.cs,同时修改其代码为:namespace Bruce
Zhang.com.Printer {///
/// Summary description for Class1. ///
public class MessagePrinter { public MessagePrinter() {// // TODO: Add constructor logic he
re//}public static void Print(string msg){Console.WriteLine(msg);}}}在MessagePrinter类
中,我们注意到并没有Main0方法,因为它不是应用程序。新增加的PrintO方法,能够接收一个字符
串,然后在控制台中显示出来。
T.
4、编译Printer项目。鼠标右键单击该项目名,在菜单中选择"Build"。成功编译后,找到文件夹
Printer/bin/debug,可以发现有文件BruceZhang.com.Printer.dll,这就是最后形成的程序集文
件。
5、关联这两个项目。我们希望是在FirstExample项目中用到Printer项目的Print(0方法,前提是
需要在FirstExample项目中添加对Printer项目的引用。右键单击FirstExample项目的“Reference",
选择"Add Reference”,在对话框中选择"Project"标签,找到该项目并选中,最后如图所示:
6、现在就可以在FirstExample项目中使用MessagePrinter了。首先,在命名空间中添加对它的
使用(Using),然后再Main0方法中调用它,最后代码如下:using System;using BruceZhang.
com.Printer; namespace BruceZhang.com.FirstExample {///
/// Summary description for Class1.///
class HelloWorld {///
/// The main entry point for the application.///
[STAThread] static void Main(string[] args) ( MessagePrinter.Print(“Hello World!”); Console.R
ead0;}}}
7、运行。结果与前一个例子一样。
在这个例子中,解决方案中就包含了两个项目,一个是控制台应用程序,一个是类库。类库提供
一些基本的功能,如例子中的PrintO方法。我们常常把一些共用的方法,放到类库中。这样其他的应
用程序就可以去调用它。例如本例的控制台应用程序。如果新建的Windows应用程序,也需要这个
功能,就可以直接引用MessagePrinter的PrintO方法,而不必重复去实现。
第三篇:命名空间
本讲基本要求
*掌握:命名空间的作用及定义;如何使用命名空间。
了解:使用早期的函数库
重点、难点
+命名空间的作用及定义;如何使用命名空间。
在学习本书前面各章时,读者已经多次看到在程序中用了以下语句:using namespace std;
这就是使用了命名空间std。在本讲中将对它作较详细的介绍。
一、为什么需要命名空间(问题提出)
命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突。
在C语言中定义了3个层次的作用域,即文件(编译单元)、函数和复合语句。C++又引入了类作用
域,类是出现在文件内的。在不同的作用域中可以定义相同名字的变量,互不于扰,系统能够区别它
们。
1、全局变量的作用域是整个程序,在同一作用域中不应有两个或多个同名的实体(enuty),包括
变量、函数和类等。
例:如果在文件中定义了两个类,在这两个类中可以有同名的函数。在引用时,为了区别,应该
加上类名作为限定:class A /∥声明A类
{ public:
void funl0;/∥声明A类中的funl函数
private:
int i; B;
void A::funl0/∥定义A类中的funl函数
[owwm}
class B//声明B类
{ public:
void funl0;//B类中也有funl函数
void fun20; };
void B::funl0//定义B类中的funl函数
{}这样不会发生混淆。
在文件中可以定义全局变量(global variable),它的作用域是整个程序。如果在文件A中定义了
一个变量a int a=3;
在文件B中可以再定义一个变量a int a=5;在分别对文件A和文件B进行编译时不会有问题。但
是,如果一个程序包括文件A和文件B,那么在进行连接时,会报告出错,因为在同一个程序中有两
个同名的变量,认为是对变量的重复定义。
可以通过extern声明同一程序中的两个文件中的同名变量是同一个变量。如果在文件B中有以下
声明:extem int a;
表示文件B中的变量a是在其他文件中已定义的变量。由于有此声明,在程序编译和连接后,文件
A的变量a的作用域扩展到了文件B。如果在文件B中不再对a赋值,则在文件B中用以下语句输出的是
文件A中变量a的值:cout<
2、程序中就会出现名字冲突。
在简单的程序设计中,只要人们小心注意,可以争取不发生错误。但是,一个大型的应用软件,
往往不是由一个人独立完成的,而是由若干人合作完成的,不同的人分别完成不同的部分,最后组合
成一个完整的程序。假如不同的人分别定义了类,放在不同的头文件中,在主文件(包含主函数的文
件)需要用这些类时,就用#include命令行将这些头文件包含进来。由于各头文件是由不同的人设计
的,有可能在不同的头文件中用了相同的名字来命名所定义的类或函数。例4名字冲突
程序员甲在头文件headerl.h中定义了类Student和函数fun。/∥例4中的头文件header1(头文
件1,没其文件名为cc8-4-h1.h)#include #include using nbmespace std;class Student //声明St
udent类
{ public: Student(int n,string nam,int a) { num=n;name=nam;age=a;} void get_data0; pri
vate:int num;string name;int age;};void Student:get_data(//成员函数定义{cout< using n
amespace std;#include"header1.h"/∥注意要用双引号,因为文件一般是放在用用户目录中的int
main){Student stud1(101,“Wang",18);//定义类对象studl stud1.get data(0;cout<
101 Wang 182.82843如果程序员乙写了头文件header2.h,在其中除了定义其他类以外,还
定义了类Student和函数fun,但其内容与头文件headerl.h中的Student和函数fun有所不同。/∥例
4中的头文件header2 #include #include using namespace std;class Student//声明Student类{
public:Student(int n,string nam,char s)/∥参数与headerl中的student不同
{ num=n;name=nam;sex=s;} void get data0; private: int num; string name; char sex; };//
此项与headerl不同
void Student:get_data0/∥成员函数定义{cout<
double fun(double a,double b)/∥定义全局函数
(return sqrt(a-b);}//返回值与headerl中的fun函数不同/∥头文件2中可能还有其他内容
假如主程序员在其程序中要用到headerl.h中的Student和函数fun,因而在程序中包含了头文
件headerl.h,同时要用到头文件header2.h中的一些内容(但对header2.h中包含与headerl.h中
的Student类和fun函数同名而内容不同的类和函数并不知情,因为在一个头文件中往往包含许多不
同的信息,而使用者往往只关心自己所需要的部分,而不注意其他内容),因而在程序中又包含了头
文件header2.h。如果主文件(包含主函数的文件)如下:#include using namespace std;#includ
e"header1.h"//包含头文件I#include"header2.h"//包含头文件2 int main0{Student stud1(10
1,“Wang”,18); stud1.get_data(0; cout<
3、全局命名空间污染(global namespace pollution)。
在程序中还往往需要引用一些库(包括C++编译系统提供的库、由软件开发商提供的库或者用户
自己开发的库),为此需要包含有关的头文件。如果在这些库中包含有与程序的全局实体同名的实
体,或者不同的库中有相同的实体名,则在编译时就会出现名字冲突。
为了避免这类问题的出现,人们提出了许多方法,例如:将实体的名字写得长一些(包含十几个
或几十个字母和字符);把名字起得特殊一些,包括一些特殊的字符;由编译系统提供的内部全局标
识符都用下划线作为前缀,如complex0,以避免与用户命名的实体同名;由软件开发商提供的实体
的名字用特定的字符作为前缀。但是这样的效果并不理想,而且增加了阅读程序的难度,可读性降低
了。c语言和早期的C++语言没有提供有效的机制来解决这个问题,没有使库的提供者能够建立自己
的命名空间的工具。人们希望ANSIC++标准能够解决这个问题,提供一种机制、一种工具,使由库
的设计者命名的全局标识符能够和程序的全局实体名以及其他库的全局标识符区别开来。
二、什么是命名空间(解决方案)
命名空间:实际上就是一个由程序设计者命名的内存区域,程序设计者可以根据需要指定一些有
名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。
如:namespace ns1//指定命名中间nsl
{int a;
double b;}namespace是定义命名空间所必须写的关键字,nsl是用户自己指定的命名空间的名
字(可以用任意的合法标识符,这里用ns1是因为ns是namespace的缩写,含义请楚),在花括号内是
声明块,在其中声明的实体称为命名空间成员(namespace member)。现在命名空间成员包括变量a
和b,注意a和b仍然是全局变量,仅仅是把它们隐藏在指定的命名空间中而已。如果在程序中要使用
变量a和b,必须加上命名空间名和作用域分辨符“",如nsla,nsl:b。这种用法称为命名空间限定(q
ualified),这些名字(如nsl:a)称为被限定名(qualified name)。C++中命名空间的作用类似于操作系
统中的目录和文件的关系,由于文件很多,不便管理,而且容易重名,于是人们设立若干子目录,把
文件分别放到不同的子目录中,不同子目录中的文件可以同名。调用文件时应指出文件路径。
命名空间的作用:是建立一些互相分隔的作用域,把一些全局实体分隔开来。以免产生老点名叫
李相国时,3个人都站起来应答,这就是名字冲突,因为他们无法辨别老师想叫的是哪一个李相国,
同名者无法互相区分。为了避免同名混淆,学校把3个同名的学生分在3个班。这样,在小班点名叫李
相国时,只会有一个人应答。也就是说,在该班的范围(即班作用域)内名字是惟一的。如果在全校集
合时校长点名,需要在全校范围内找这个学生,就需要考虑作用域问题。如果校长叫李相国,全校学
生中又会有3人一齐喊“到”,因为在同一作用域中存在3个同名学生。为了在全校范围内区分这3名学
生,校长必须在名字前加上班号,如高三甲班的李相国,或高三乙班的李相国,即加上班名限定。这
样就不致产生混淆。
可以根据需要设置许多个命名空间,每个命名空间名代表一个不同的命名空间域,不同的命名空
间不能同名。这样,可以把不同的库中的实体放到不同的命名空间中,或者说,用不同的命名空间把
不同的实体隐蔽起来。过去我们用的全局变量可以理解为全局命名空间,独立于所有有名的命名空间
之外,它是不需要用namespace声明的,实际上是由系统隐式声明的,存在于每个程序之中。
在声明一个命名空间时,花括号内不仅可以包括变量,而且还可以包括以下类型:·变量(可以带
有初始化);·常量;
数(可以是定义或声明);·结构体;·类;·模板;
·命名空间(在一个命名空间中又定义一个命名空间,即嵌套的命名空间)。例如
namespace nsl{const int RATE=0.08;//常量doublepay;
//变量
doubletax(
∥函数
(return a
RATE; } namespacens2
∥嵌套的命名空间
(int age;}}
如果想输出命名空间nsl中成员的数据,可以采用下面的方法:cout<
cout<
可以看到命名空间的声明方法和使用方法与类差不多。但它们之间有一点差别:在声明类时在右
花括号的后面有一分号,而在定义命名空间时,花括号的后面没有分号。
三、使用命名空间解决名字冲突(使用指南)有了以上的基础后,就可以利用命名空间来解决
名字冲突问题。现在,对例4程序进行修改,使之能正确运行。
例5利用命名空间来解决例4程序名字冲突问题。
修改两个头文件,把在头文件中声明的类分别放在两个不同的命名空间中。/∥例8.5中的头文件
1, 文件名为header1.h using namespace std;#include #include namespace ns1 /∥声明命名空
间ns1{class Student//在命名空间nsl内声明Student类
{ public: Student(int n,string nam,int a) {num=n;name=nam;age=a;} void get data0; pri
vate:int num;string name;int age;};void Student:get data0//定义成员函数
{cout<
double fun(double a,double b)//在命名空间n引内定义fun函数{return sqrt(a+b);}}//例8.
5中的头文件2,文件名为header2.h #include #include namespace ns2/∥声明命名空间ns2{clas
s Student {public: Student(int n,string nam,char s) { num=n;name=nam;sex=s;} void get_dat
a0; private: int num; string name; char sex; };
void Studentget_ data() { cout<
double fun(double a,double b) {return sqrt(a-b);} } //main file #include #include “heade
r1.h”//包含头文件|#include"header2.h"//包含头文件2 int main0{ns1:Student stud1(101,“W
ang”,18);//用命名空间nsl中声明的Student类定义studt stud1.get data0;/∥不要写成ns1::studl.ge
t_data0;
cout<
ns2::Student stud2(102,“Li”,'f);//用命名空间ns2中声明的Student类定义stud2 stud2.get da
ta0; cout<
分析例4程序出错的原因是:在两个头文件中有相同的类名Student和相同的函数名fun,在把它
们包含在主文件中时,就产生名字冲突,存在重复定义。编译系统无法辨别用哪一个头文件中的Stud
ent来定义对象studl。现在两个Student和fun分别放在不同的命名空间中,各自有其作用域,互不
相干。由于作用域不相同,不会产:生名字冲突。正如同在两个不同的类中可以有同名的变量和函数
而不会产生冲突一样。
在定义对象时用ns1:Student(命名空间nsl中的Student)来定义studl,用ns2::Student(命名
空间ns2中的Student)来定义stud2。显然,nsl::Student和ns2::Student是两个不同的类,不会产生
混淆。同样,在调用fun函数时也需要用命名空间名ns]或ns2加以限定。ns1::fun0和ns2::fun(0是两
个不同的函数。注意:对象studl是用nsl::Student定义的,但对象studl并不在命名空间nsl中。st
udl的作用域为main函数范围内。在调用对象studl的成员函数get data时,应写成studl.get data
0,而不应写成nsl:studl.get data0。 程序能顺利通过编译,并得到以下运行结果:101 Wang 19
(对象studl中的数据)2.82843(/5+3的值)102 Lif(对象studg中的数据)1.41421(/5-2的值)
四、使用命名空间成员的方法从上面的介绍可以知道,在引用命名空间成员时,要用命名空间
名和作用域分辨符对命名空间成员进行限定,以区别不同的命名空间中的同名标识符。即:命名空间
名::命名空间成员名
这种方法是有效的,能保证所引用的实体有惟一的名字。但是如果命名空间名字比较长,尤其在
有命名空间嵌套的情况下,为引用一个实体,需要写很长的名字。在一个程序中可能要多次引用命名
空间成员,就会感到很不方便。1、使用命名空间别名
可以为命名空间起一个别名(namespace alias),用来代替较长的命名空间名。如namespace T
elevision //声明命名空间,名为Television{.…}可以用一个较短而易记的别名代替它。如:
namespace TV=Television;//别名TV与原名Television等价
也可以说,别名TV指向原名Television,在原来出现Television的位置都可以无条件地用TV来代
替。
2、使用using命名空间成员名
using后面的命名空间成员名必须是由命名空间限定的名字。例如:using nsl:Student;以上
语句声明:在本作用域(using语句所在的作用域)中会用到命名空间ns1中的成员Student,在本作用
域中如果使用该命名空间成员时,不必再用命名空间限定。例如在用上面的using声明后,在其后程
序中出现的Student就是隐含地指nsl:Student。
using声明的有效范围是从using语句开始到using所在的作用域结束。如果在以上的using语句
之后有以下语句:
Student studl(101,“Wang”,18);//此处的Student相当于ns1::Student上面的语句相当于
nsl::Student studl(101, “Wang”, 18); 又如
using nsl:fun;/∥声明其后出现的fun是属于命名空间nsl中的fun cout<
但是要注意:在同一作用域中用using声明的不同命名空间的成员中不能有同名的成员。例如:
usmgnsl::Student;/∥声明其后出现的Student是命名空间nsl中的Student usmgns2::Studen
t;/∥声明其后出现的Student是命名空间ns2小的Student Student stud1;∥请问此处的Student
是哪个命名中间中的Student?产生了二义性,编译出错。
3、使用using namespace命名空间名
用上面介绍的using命名空间成员名,一次只能声明一个命名空间成员,如果在一个命名空间中
定义了10个实体,就需要使用10次using命名空间成员名。能否在程序中用一个语句就能一次声明一
个命名空间中的全部成员呢?C++提供了using namespace语句来实现这一目的。using namespac
e语句的一般格式为using namespace 命名空间名;例如
using nanlespace nsl;
声明了在本作用域中要用到命名空间nsl中的成员,在使用该命名空间的任何成员时都不必用命
名空间限定。如果在作了上面的声明后有以下语句:Student studl(101,“Wang”,18);/∥Stude
nt隐含指命名中间nsl中的Student cout<
cout<
Student stud2(102, “Li”, ‘r’); stud2.get data(0;
coutt<
五、无名的命名空间
以上介绍的是有名字的命名空间,C++还允许使用没有名字的命名空间,如在文件A中声明了以
下的无名命名空间:
namespace/∥命名空间没有名字{void fun()/∥定义命名空间成员{cout<<“OK.”<
则执行无名命名空间中的成员fun函数,输出“OK.”。
在本程序中的其他文件中也无法使用该fun函数,也就是把fun函数的作用域限制在本文件范围
中。可以联想到:在C浯言中可以用static声明一个函数,其作用也是使该函数的作用域限于本文件。
C++保留了用static声明函数的用法,同时提供了用无名命名空间来实现这一功能。随着越来越多的
C++编译系统实现了ANSIC++建议的命名空间的机制,相信使用无名命名空间成员的方法将会取代
以前习惯用的对全局变量的静态声明。
六、标准命名空间std为了解决C++标准库中的标识符与程序中的全局标识符之间以及不同库中
的标识符之间的同名冲突,应该将不同库的标识符在不同的命名空间中定义(或声明)。标准C++库的
所有的标识符都是在一个名为std的命名空间中定义的,或者说标准头文件(如iostream)中函数、
类、对象和类模板是在命名空间std中定义的。std是standard(标准)的缩写,表示这是存放标准库的
有关内容的命名空间,含义请楚,不必死记。
这样,在程序中用到C++标准库时,需要使用std作为限定。如
std::cout<<“OK.”<
这样,在std中定义和声明的所有标识符在本文件中都可以作为全局量来使用。但是应当绝对保
证在程序中不出现与命名空间std的成员同名的标识符,例如在程序中不能再定义一个名为cout的对
象。由于在命名空间std中定义的实体实在太多,有时程序设计人员也弄不请哪些标识符已在命名空
间std中定义过,为减少出错机会,有的专业人员喜欢用若干个“using命名空间成员“声明来代替“usin
g namespace命名空间"声明,如using Std::string;using Std::cout;using Std::cin;
等。为了减少在每一个程序中都要重复书写以亡的using声明,程序开发者往往把编写应用程序
时经常会用到的命名空间std成员的usmg声明组成一个头文件,然后在程序中包含此头文件即可。
如果阅读了多种介绍C++的书,可能会发现有的书的程序中有using namespace语句,有的则
没有。有的读者会提出:究竟应该有还是应该没有?应当说:用标准的C++编程,是应该对命名空间s
td的成员进行声明或限定的(可以采取前面介绍过的任一种方法)。但是目前所用的C++库大多是几年
前开发的,当时并没有命名空间,库中的有关内容也没有放在std命名空间中,因而在程序中不必对s
td进行声明。
七、使用早期的函数库
C语言程序中各种功能基本上都是由函数来实现的,在C语言的发展过程中建立了功能丰富的函
数库,C++从C语言继承了这份宝贵的财富。在C++程序中可以使用C语言的函数库。如果要用函数
库中的函数,就必须在程序文件中包含有关的头文件,在不同的头文件中,包含了不同的函数的声
明。
在C++中使用这些头文件有两种方法。
1、用C语言的传统方法
头文件名包括后缀.h,如stdio.h,math.h等。由于C语言没有命名空间,头文件并不存放在命
名空间中,因此在C++程序文件中如果用到带后缀.h的头文件时,不必用命名空间。只需在文件中
包含所用的头文件即可。如#include
2、用C++的新方法
C++标准要求系统提供的头文件不包括后缀.h,例如iostream、string。为了表示与C语言的
头文件有联系又有区别,C++所用的头文件名是在C语言的相应的头文件名(但不包括后缀.h)之前加
一字母c。例如,C语言中有关输入与输出的头文件名为stdio.h在C++中相应的头文件名为cstdio。
C语言中的头文件math.h,在C++中相应的头文什名为cmath。C语言中的头文件string.h在C+
+中相应的头文件名为cstring。注意在C++中,头文件cstnng和头文件strmg不是同一个文件。前者
提供C语言中对字符串处理的有关函数(如strcmp,ctrcpy)的声明,后者提供C++中对字符串处理的
新功能。此外,由于这些函数都是在命名空间std中声明的,因此在程序中要对命名空间std作声明。
如:
#include #include using namespace std;
目前所用的大多数C++编译系统既保留了c的用法,又提供丁C++的新方法。下面两种用法等
价,可以任选。C传统方法C++新方法
#include #include #include #include #include #include using namespace std;
第五篇:PHP命名空间
PHP命名空间(Namespace)的使用详解
对于命名空间,官方文档已经说得很详细[查看],我在这里做了一下实践和总结。
命名空间一个最明确的目的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,
否则会产生一个致命的错误。这种情况下只要避免命名重复就可以解决,最常见的一种做法是约定一
个前缀。例:项目中有两个模块:article和message board,它们各自有一个处理用户留言的类Co
mment。之后我可能想要增加对所有用户留言的一些信息统计功能,比如说我想得到所有留言的数
量。这时候调用它们Comment提供的方法是很好的做法,但是同时引入各自的Comment类显然是
不行的,代码会出错,在另一个地方重写任何一个Comment也会降低维护性。那这时只能重构类
名,我约定了一个命名规则,在类名前面加上模块名,像这样:Article Comment、MessageBoar
d Comment可以看到,名字变得很长,那意味着以后使用Comment的时候会写上更多的代码(至
少字符多了)。并且,以后如果要对各个模块增加更多的一些整合功能,或者是互相调用,发生重名
的时候就需要重构名字。当然在项目开始的时候就注意到这个问题,并规定命名规则就能很好的避免
这个问题。另一个解决方法可以考虑使用命名空间。
注明:
本文提到的常量:PHP5.3开始const关键字可以用在类的外部。const和define都是用来声明常
量的(它们的区别不详述),但是在命名空间里,define的作用是全局的y而const则作用于当前空
间。我在文中提到的常量是指使用const声明的常量。
基础
命名空间将代码划分出不同的空间(区域),每个空间的常量、函数、类(为了偷懒,我下边都
将它们称为元素)的名字互不影响,这个有点类似我们常常提到的’封装’的概念。创建一个命名空间
需要使用namespace关键字,这样:复制代码代码如下:<?php /∥创建一个名为'Article'的命名空间namespace Article;?>
要注意的是,当前脚本文件的第一个命名空间前面不能有任何代码,下面的写法都是错误的:
复制代码代码如下://例一
/∥在脚本前面写了一些逻辑代码<?php $path=“/”;class Comment{}namespace Article;?

∥例二
/∥在脚本前面输出了一些字符<?php namespace Article;?>
为什么要说第一个命名空间呢?因为同一脚本文件中可以创建多个命名空间。
下面我创建了两个命名空间,顺便为这两个空间各自添加了一个Comment类元素:复制代码代
码如下:<?php /∥创建一个名为'Article'的命名空间 namespace Article;/∥此Comment属于Article空间的元素 class Comment {) /∥创建一个名为'MessageBoard'的命名空间namespace MessageBoard;/∥此Comment属于 MessageBoard空间的元素class Comment{}?>
在不同空间之间不可以直接调用其它元素,需要使用命名空间的语法:复制代码代码如下:<?p hp namespace Article; class Comment {} namespace MessageBoard;class Comment{}//调用当前空间(MessageBoard)的Comm ent类$comment=new Comment0;//调用Article空间的Comment类 $article comment = new Article\Comment0; ?>
可以看到,在MessageBoard空间中调用article空间里的Comment类时,使用了一种像文件路
径的语法:\空间名\元索名
除了类之外,对函数和常量的用法是一样的,下面我为两个空间创建了新的元素,并在Message
Board空间中输出了它们的值。复制代码代码如下:<?php namespace Article;const PATH='/art icle'; function getCommentTotal0 {return 100;} class Comment {} namespace MessageBoard; const PATH = '/message_board'; function getCommentTotal 0{return 300;}class Comment{}/∥调用当前空间的常量、函数和类echo PATH;/∥/message_b oard echo getCommentTotal0;//300$comment=new Comment0;∥调用Article空间的常 量、 函数和类echo \Article\PATH;///article echo \Article\getCommentTotal0;//100 $article_ comment = new VArticle\Comment0; ?>
然后我的确得到了Article空间的元素数据。子空间
命名空间的调用语法像文件路径一样是有道理的,它允许我们自定义子空间来描述各个空间之间
的关系。抱歉我忘了说,article和message board这两个模块其实都是处于同一个blog项目内。如
果用命名空间来表达它们的关系,是这样:复制代码代码如下:<?php //我用这样的命名空间表示处于blog 下的article模块 namespace Blog\Article;class Commen t{ //我用这样的命名空间表示处于blog下的message board模块namespace Blog\MessageBoa rd;class Comment{}//调用当前空间的类 $comment = new CommentO;//调用Blog Article空间的类 $article comment = new \Blog\Article\Comment0; ?>
而且,子空间还可以定义很多层次,比如说Blog\Article\Archives\Date
公共空间
我有一个common_inc.php脚本文件,里面有一些好用的函数和类:复制代码代码如下:<?php function getIP0 {} class FilterXSS {}?>
在一个命名空间里引入这个脚本,脚本里的元素不会归属到这个命名空间。如果这个脚本里没有
定义其它命名空间,它的元素就始终处于公共空间中:复制代码代码如下:<?php namespace Blog\Article;//弓|入脚本文件 include'!./common_inc.php';$filter_XSS=new FilterXSS0;/∥出现致命错误: 找不到Blog\A rticle\FilterXSS类$filter XSS=new\FilterXSSO;//正确?>
调用公共空间的方式是直接在元素名称前加\就可以了,否则PHP解析器会认为我想调用当前空
间下的元素。除了自定义的元素,还包括PHP自带的元素,都属于公共空间。
要提一下,其实公共空间的函数和常量不用加\也可以正常调用(不明白PHP为什么要这样
做),但是为了正确区分元素,还是建议调用函数的时候加上
名称术语
在说别名和导入之前,需要知道关于空间三种名称的术语,以及PHP是怎样解析它们的。官方文

档说得非常好,我就直接拿来套了。
1.非限定名称,或不包含前缀的类名称,例如KaTeX parse error: Undefined control sequence: \Article at position 37: …。如果当前命名 空间是Blog\̲A̲r̲t̲i̲c̲l̲e̲,Comment将被解析为Bl…comment=new Article\Comment0;。如果当前的命
名空间是Blog,则Comment会被解析为Blog\Article\Comment。如果使用Comment的代码不包
含在任何命名空间中的代码(全局空间中),则Comment会被解析为Comment。
3.完全限定名称,或包含了全局前缀操作符的名称,例如KaTeX parse error: Undefined control sequence: \Article at position 12: comment=new\̲A̲r̲t̲i̲c̲l̲e̲\Commen tO;。在这种…blog_comment=new CommentO;//限定名称,表示相对
于Blog空间
//这个调用将被解析成 Blog\Article\CommentO;KaTeX parse error: Undefined control sequence: \Commen at position 30: …t = new Article\̲C̲o̲m̲m̲e̲n̲ ̲t0;∥类前面没有反斜杆\∥完…article_comment =new\Blog\Comment0;/∥类前面有反斜杆/∥完全限定名称,表示绝
对于Blog空间
//这个调用将被解析成 Blog\Article\Comment(O;KaTeX parse error: Undefined control sequence: \Blog at position 23: …_comment = new \̲B̲l̲o̲g̲\Article\Co mme…article_comment = new Article\CommentO;/∥
为命名空间使用别名 use Blog\Article as Arte;//使用别名代替空间名
KaTeX parse error: Undefined control sequence: \Comment at position 27: …ment = new Arte\̲C̲o̲m̲m̲e̲n̲t̲/0;//导入一个类 use …article comment = new
Comment0;//为类使用别名
use Blog\Article\Comment as Comt;∥使用别名代替空间名
KaTeX parse error: Undefined control sequence: \Article at position 112: … namespace Blog\̲A̲r̲t̲i̲c̲l̲e̲; class Comment…article_comment= new Comment/O;/∥与当前空间的Comme
nt发生冲突,程序产生致命错误∥为类使用别名
use Blog\Article\ Comment as Comt;$article_comment = new Comt0;//与当前空间的Co
mt发生冲突,程序产生致命错误?>动态调用
PHP提供了namespace关键字和_NAMESPACE_魔法常量动态的访问元素,NAMESPACE
可以通过组合字符串的形式来动态访问:复制代码代码如下:<?php namespace Blog\Article; const PATH = '/Blog/article'; class Co mment {} //namespace关键字表示当前空间echo namespace\PATH;///Blog/article $comment = ne w namespace\CommentO;//魔法常量_NAMESPACE_的值是当前空间名称 echo __NAMESPAC E_;//Blog\Article //可以组合成字符串并调用 $comment_class_name = __NAMESPACE__. "\Comment'; $comment = new $comment_c lass_name0;?>
字符串形式调用问题
上面的动态调用的例子中,我们看到了字符串形式的动态调用方式,如果要使用这种方式要注意
两个问题。
1.使用双引号的时候特殊字符可能被转义复制代码代码如下:<?php namespace Blog\Article;class name{}//我是想调用Blog\Article\name $class_name =__ NAMESPACE_."\name";/∥但是\n将被转义为换行符 $name = new $class_nameO;//发生致命 错误?> 2.不会认为是限定名称 PHP在编译脚本的时候就确定了元素所在的空间,以及导入的情况。而在解析脚本时字符串形式 调用只能认为是非限定名称和完全限定名称,而永远不可能是限定名称。复制代码代码如下:<?php namespace Blog;//导入Common类 use Blog\Article\Common;//我想使用非限定名称调用Blog\Article\Common $common cla ss_name='Common';/∥实际会被当作非限定名称,也就表示当前空间的Common类,但我当前类 没有创建Common类$common=new $common class name0;//发生致命错误:Common类 不存在//我想使用限定名称调用Blog\Article\Common $common class name='Article\Comm on';/∥实际会被当作完全限定名称,也就表示Article空间下的Common类,但我下面只定义了Blog \Article空间而不是Article空间 $common=new $common class name(0;//发生致命错误:Article\Common类不存在 namespace Blog\Article;class Common {}?>总结
我对PHP的命名空间刚刚接触,也不能随便给一些没有实践的建议。我个人认为命名空间的作用
和功能都很强大,如果要写插件或者通用库的时候再也不用担心重名问题。不过如果项目进行到一定
程度,要通过增加命名空间去解决重名问题,我觉得工作量不会比重构名字少。也不得不承认它的语
法会对项目增加一定的复杂度,因此从项目一开始的时候就应该很好的规划它,并制定一个命名规
范。

VS解决方案、命名空间和项目的关系相关推荐

  1. VS同一解决方案的不同项目的命名空间名字唯一

    VS同一解决方案的不同项目的命名空间名字要不一样.譬如开发一个DLL,命名空间是Viewer,为了测试DLL,又建立了一个测试项目,命名空间名字也是Viewer,会触发异常: System.TypeL ...

  2. 【解决方案】SpringCloud项目优雅发版、部署

    [解决方案]SpringCloud项目优雅发版.部署 参考文章: (1)[解决方案]SpringCloud项目优雅发版.部署 (2)https://www.cnblogs.com/fonxian/p/ ...

  3. .Net Core新建解决方案,添加项目引用,使用VSCode调试

    .Net Core新建解决方案,添加项目引用,使用VSCode调试 参考文章: (1).Net Core新建解决方案,添加项目引用,使用VSCode调试 (2)https://www.cnblogs. ...

  4. 解决关于VS无法加载解决方案中的项目的问题

    解决关于VS无法加载解决方案中的项目的问题 解决办法: 1.关闭vs 2.到缓存目录下,删除相关缓存,删除ComponentModelCache文件夹及包含的文件. C:\Users\ADMIN\Ap ...

  5. 小说漫画,影视系统,搭建一站式解决方案小说红利项目火爆

    搭建小说漫画app/h5,包上架支持多语言 搭建动漫影视app 支持m3u8 包上架 源码稳定 支持采集 官网:www.caizixiaoshuo.com 小说漫画,影视系统,搭建一站式解决方案 小说 ...

  6. 谷歌发布声明撇清与棱镜项目的关系

    谷歌在官方博客发布公开信,要求美国司法与政府机构公开美国政府索要个人信息有关的细节,从而撇清自己同"棱镜"项目的关系.做出类似表态的还有微软.Facebook和Twitter在内的 ...

  7. [原创]关于在VS解决方案下使用文件夹管理多个项目层次关系的说明

    由于所创建的应用项目或类库项目较多,于是将这些类库放到一个文件夹下.在VS解决方案下确实能看到一个文件夹下多个类库项目这种层次关系.如下图所示: 但打开"我的电脑",看到的只有类库 ...

  8. 解决方案和项目的关系_项目经理入门知识系列之《项目团队的职责分工》

    项目团队的组织结构 组织结构 项目经理职责 整合制定项目计划所需的活动. 整合执行项目计划所需的活动. 整合进行范围变更所需的活动. 1.目经理负责对横跨多个职能线的活动进行协调和整合. 整合管理 2 ...

  9. vs中项目解决方案和项目的关系

    http://blog.csdn.net/tianditongxing/article/details/41038695 vs项目配置属性详解:http://tinggo.iteye.com/blog ...

最新文章

  1. R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(输出多个分组、自定义颜色配置)实战
  2. PKG_CONFIG_PATH 、LD_LIBRARY_PATH、PATH三个的作用
  3. linux网卡入流速,linux下简单限制网卡速度与
  4. 【uni-app】在新窗口中打开链接
  5. 如何在Java代码中使用SAP云平台CloudFoundry环境的环境变量
  6. java实现红包要多少钱_Java实现抢红包算法,附完整代码(公平版和手速版)
  7. hadoop的开发工具_Hadoop开发工具简介
  8. JavaFX 2:如何加载图像
  9. 攻防世界web高手进阶php_rce,php_rce 攻防世界xctf web
  10. Spring Cloud实战小贴士:版本依赖关系
  11. linux下安装apache与php;Apache+PHP+MySQL配置攻略
  12. SQL:postgresql一条sql语句查询多个count
  13. 基于麻雀优化的BP神经网络(分类应用) - 附代码
  14. java条件触发,触发器触发条件是什么?更改数据时实现方法是什么?
  15. 利用模拟低通滤波器设计带通、带阻、高通模拟滤波器
  16. sap 双计量单位_SAP 基本计量单位更改(转载)
  17. 无线通信中载波带宽是什么?
  18. Spring Kafka 之 @KafkaListener 单条或批量处理消息
  19. 模拟蒙蒂霍而悖论游戏——三门游戏python
  20. btrfs + snapper快照使用

热门文章

  1. ROS小车——登录和简单控制(1)
  2. 维特智能高精度三轴加速度计ros角度倾角传感器陀螺仪震动HWT9053
  3. recalc_task_prio函数
  4. 什么是基金分红?基金分红的意义 基金分红种类 基金分红是什么意思
  5. vue 配合钉钉鉴权及钉钉 API 使用方法
  6. 坐标旋转公式(推导)
  7. Chrome浏览器下载Word、Excel、PPT,打开提示错误问题
  8. 艺考生文化课分数线丨各个省份去年的艺考生文化分数线最低分是多少?
  9. 【机器学习】ROC曲线与PR曲线
  10. hdu4528小明系列故事——捉迷藏(bfs)