精华内容
下载资源
问答
  • 对于.NET应用的开发人员而言,以Visual Studio(简称VS)作为首选的开发工具应当是一种最自然不过的选择了。毕竟这款IDE提供了各种优秀的特性:智能提示、调试、包管理等等,而且如今绝大部分特性在免费的Community...

    对于.NET应用的开发人员而言,以Visual Studio(简称VS)作为首选的开发工具应当是一种最自然不过的选择了。毕竟这款IDE提供了各种优秀的特性:智能提示、调试、包管理等等,而且如今绝大部分特性在免费的Community版本中都可以任意使用。这样看来,似乎已经没有选择其他工具的必要了。

    话虽如此,但在某些场合下我们仍然可以选择脱离Visual Studio这样的IDE而进行.NET代码的开发。最近,一位名叫Patrick Lambert的开发者在他的博客文章中介绍了不使用Visual Studio进行.NET Windows应用的过程。

    Patrick认为,选择脱离VS环境进行开发有几点可能的理由:一是开发者或许想深入地了解一下.NET应用的编译过程,而不希望被图形用户界面蒙蔽了双眼。二是开发者或许出于某些原因,例如平台或工作环境的原因而无法安装VS。三是开发者只打算开发一个非常简单的应用,为了一个5KB大小的应用去下载一个5GB大小的IDE好像有些太过奢侈。如果以上任何一点原因适用于你的情况,就可以考虑尝试一下Patrick的教程。

    必备依赖

    在开始编码之前,首先看看有哪些依赖项是必须的,这里假设我们选择C#语言开发基于.NET Framework的应用。好消息是.NET Framework不再依赖于其他组件,只要在操作系统中安装过它,就无需再安装任何组件了!而且许多系统在安装时会自动包括.NET Framework,可以通过检查C:\Windows\Microsoft.NET\Framework目录确认是否已安装。在这个目录下会列出每个已安装的版本的子目录。

    接下来要搞定编译的问题,在.NET Framework中已经自带了C#编译器。这篇教程中要用到两个二进制文件,其中csc.exe就是C#编译器,而msbuild.exe则是负责读取项目文件(例如.csproj文件)并进行编译的工具。也就是说,如果某人发送给你一个Visual Studio项目文件,那么你也能够在不安装Visual Studio的情况下,通过运行msbuild对源代码进行编译。

    .NET项目的结构

    Patrick接下来介绍了VS项目的结构,虽然在本篇教程中不需要创建项目文件,但对项目结构的理解可以帮助我们了解一些概念。通常来说,在新建Windows项目时,VS会自动创建一个Program.cs文件作为入口、一个包含了代码所依赖资源信息的.csproj文件、包含二进制名称、版本号等信息的AssemblyInfo.cs文件,以及包含了自定义配置信息的App.config文件。其中App.config这个文件主要的用途是配置一些相关的依赖信息,例如数据库连接字符串、Social Login的帐号等等。

    主体代码

    接下来,Patrick展示了一段非常简单的代码。由于这篇教程不使用Visual Studio等IDE,因此可以随意选择最喜爱的文本编辑器编写以下代码,并保存为helloworld.cs文件:

    using System;

    namespace HelloWorld

    {

    public class Program

    {

    static void Main(string[] args)

    {

    Console.WriteLine("Hello world!");

    }

    }

    }

    如你所见,这段代码的作用就是简单地在控制台中输出“Hello World!”而已。因为我们的专注点不在C#代码本身,因此不必纠结于它太过简单。编译指令也很简单,只需指定编译器文件的位置,通过/out:参数指定的输出文件,并在最后指定源代码文件,就能够创建可运行的应用程序了。参考如下命令:

    E:\code> C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /out:helloworld.exe helloworld.cs

    Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.5420

    for Microsoft (R) .NET Framework version 3.5

    Copyright (C) Microsoft Corporation. All rights reserved.

    E:\code> helloworld

    Hello world!

    E:\code>

    添加程序集信息

    现在你已经得到了这个可运行的exe文件了,但如果右键检查一下文件的详细信息,你会发觉诸如文件描述、版本号与版权等信息都是空白的。这些信息应该是由程序集所定义的,而通常我们都是在VS中填写这些信息的。其实即使没有VS也一样简单,只需修改一下helloworld.cs即可:

    using System;

    using System.Reflection;

    [assembly: AssemblyTitle("Hello World Application")]

    [assembly: AssemblyCopyright("(C) 2015 John Doe")]

    [assembly: AssemblyFileVersion("1.0")]

    namespace HelloWorld

    {

    // class definition

    }

    这里省略了类的定义,因为这部分没有任何变化。变化之一是引入了System.Reflection这个命名空间,随后为程序集提供了相应的信息。当我们再次编译后,就能够在可运行文件的详细信息中找到他们了。

    具有图形界面的应用

    在介绍了控制台应用的创建之后,Patrick又介绍了脱离VS进行图形界面应用的创建过程。微软现在推荐通过XAML语言创建统一应用,这种语言基于XML定义应用的界面。不过出于简单起见,Patrick在这里选择了创建基于Windows Forms的桌面应用。

    经过修改的helloworld.cs代码如下:

    using System;

    using System.Reflection;

    using System.Windows.Forms;

    [assembly: AssemblyTitle("Hello World Application")]

    [assembly: AssemblyCopyright("(C) 2015 John Doe")]

    [assembly: AssemblyFileVersion("1.0")]

    namespace HelloWorld

    {

    public class Program

    {

    static void Main(string[] args)

    {

    MessageBox.Show("Hello world!", "Hi!");

    }

    }

    }

    这段代码与改动前非常相似,一个变更是引入了System.Windows.Forms命名空间,另一个则是通过MessageBox输出信息。在运行时,Windows系统会自行处理图形窗口的创建等工作。运行结果如下:

    9d266f5022d5ad31e2c59d0624d4fb13.png

    引用第三方类库

    最后,Patrick介绍了如何在应用中引用第三方资源,这次的代码通过使用Amazon AWS SDK实现了一个发送短消息通知的功能:

    using System;

    using Amazon;

    using Amazon.SimpleNotificationService;

    using Amazon.SimpleNotificationService.Model;

    namespace AwsSnsSample

    {

    class Program

    {

    public static void Main(string[] args)

    {

    var sns = new AmazonSimpleNotificationServiceClient();

    sns.Publish(new PublishRequest

    {

    Subject = "Hi!",

    Message = "Hello world!",

    TopicArn = "arn:aws:sns:us-west-2:0000000000:snstest1"

    });

    }

    }

    }

    在进行编译之前,首先要下载一个AWS SDK,并设置相应的IAM帐号,以用于发送信息。在编译命令中,要点在于通过/r:选项指定AWS的引用:

    E:\code> C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /out:helloworld.exe /r:"C:\Program Files (x86)\AWS SDK for .NET\bin\Net35\AWSSDK.dll" helloworld.cs

    虽然本文中所介绍的应用比较简单,但其实原理都是相通的,通过类似的方法也可以创建基于ASP.NET、Azure或WPF等应用。虽然Patrick并不建议在专业应用开发中采取这种比较原始的方式,但了解这一过程能够帮助.NET开发者理解编译的过程,这些知识点将对他们在进行专业应用开发中提供很大的帮助。

    0b1331709591d260c1c78e86d0c51c18.png

    展开全文
  • Boost中应用的泛型编程技术 2009年10月23日   何谓泛型编程泛型编程(Generic Programming)关注于产生通用的软件组件,让这些组件在不同的应用场合很容易地重用。在C++中,类模板和函数模板是进行泛型编程...
    Boost中应用的泛型编程技术 
    2009年10月23日
      
    何谓泛型编程泛型编程(Generic Programming)关注于产生通用的软件组件,让这些组件在不同的应用场合都能很容易地重用。在C++中,类模板和函数模板是进行泛型编程极为有效的机制。有了这两大利器,我们在实现泛型化的同时,并不需要付出效率的代价。
      作为泛型编程的一个简单例子,让我们看一下在C库中如何让memcpy()函数泛型化。一种实现方法可能是这样的:[b]
      void* memcpy(void* region1, const void* region2, size_t n){ const char* first = (const char*)region2; const char* last = ((const char*)region2) + n; char* result = (char*)region1; while (first != last) *result++ = *first++; return result;} [/b]
      这个memcpy()函数已经在一定程度上进行了泛型化,采取的措施是使用void*,这样该函数就可以拷贝不同类型的数组。但如果我们想拷贝的数据不是放在数组里,而是由链表来存放呢?我们能不能扩展这个概念,让它可以拷贝任意的序列?看看memcpy()的函数体,这个函数对传入的序列有一个_最小需求_:它需要用某种形式的指针来遍历这个序列;访问指针正指向的元素;把元素写到目的地;比较指针以判断何时停止拷贝。C++标准库把这样的需求进行分组,称之为概念(concepts)。在这个例子中就有输入迭代器(对应于region1)和输出迭代器(对应于region2)这两个概念。
      如果我们把memcpy()用函数模板重写,使用输入迭代器和输出迭代器作为模板参数来描述对序列的需求,我们就可以写出一个具有较高重用性的copy()函数:[b]
      template OutputIteratorcopy(InputIterator first, InputIterator last, OutputIterator result){ while (first != last) *result++ = *first++; return result;} [/b]
      使用这个泛型的copy()函数,我们可以拷贝各种各样的序列,只要它满足了我们指定的需求。对外提供了迭代器的链表,比如std::list,也可以通过我们的copy()函数来拷贝:[b]
      #include #include #include int main(){ const int N = 3; std::vector region1(N); std::list region2; region2.push_back(1); region2.push_back(0); region2.push_back(3); std::copy(region2.begin(), region2.end(), region1.begin()); for (int i = 0; i 看起来是这个样子:[b]
      template struct iterator_traits { typedef ... iterator_category; typedef ... value_type; typedef ... difference_type; typedef ... pointer; typedef ... reference;}; [/b]
      该traits的value_type可以让泛型代码得知该迭代器所“指向”的是何种类型的数据;而iterator_category对迭代器的能力进行分类,针对不同类型的迭代器我们选择与之适应的最高效的算法。
      traits模板有一个很重要的特点:它们是非侵入的(non-intrusive)。我们可以为任何类型提供相关信息,不管它是内建的类型,还是第三方的库中提供的类型。为了给某一特定类型指定traits,一般采用部分特化或者全特化traits模板的方式。
      欲更深入的了解std::iterator_traits,可以参阅SGI提供的资料。std::numeric_limits也采用了traits技术,提供表示各内建数值类型取值范围的常量值。标记分派
      另外有一种技术经常与traits合用,那就是标记分派。它依据类型的属性,通过函数重载进行分派。一个很好的例子就是std::advance()函数。这个函数的功能是将一个迭代器递增n次,对于不同类型的迭代器可以有各自优化的实现方法。如果是随机访问迭代器(可以以任意的距离前后跳转),advance()函数可以用i+=n来实现,既简单又高效,只需要常量时间。而其它的迭代器必须一步一步地递增,需要线性的时间复杂度。如果是双向迭代器,n就可能为负值,因此必须判断对迭代器到底是增还是减。
      标记分派和traits类的联系很紧密。分派所依据的属性(在这个例子中是iterator_category)一般都是通过traits类来取得。主advance()函数从iterator_traits中获得对应于该iterator的iterator_category,然后调用重载过的advance_dispach()函数。编译器依据作为参数传给advance_dispach()的iterator_category,选择合适的重载版本。标记只是一个极其简单的类,它的唯一任务就是为标记分派或者其它类似技术传递必要的信息。[b]
      namespace std { struct input_iterator_tag { }; struct bidirectional_iterator_tag { }; struct random_access_iterator_tag { }; namespace detail { template void advance_dispatch(InputIterator& i, Distance n, input_iterator_tag) { while (n--) ++i; } template void advance_dispatch(BidirectionalIterator& i, Distance n, bidirectional_iterator_tag) { if (n >= 0) while (n--) ++i; else while (n++) --i; } template void advance_dispatch(RandomAccessIterator& i, Distance n, random_access_iterator_tag) { i += n; } } template void advance(InputIterator& i, Distance n) { typename iterator_traits::iterator_category category; detail::advance_dispatch(i, n, category); }} [/b]适配器
      适配器是一种类模板,建立在其它类型之上,提供新的接口或者行为。标准库中就使用了适配器,比如std::reverse_iterator通过反转迭代器的递增/递减行为,适配了迭代器,还有std::stack,通过适配标准容器,提供一个简单的堆栈接口。
      在这里可以找到标准库中所用适配器的深入阐述。类型生成器
      类型生成器的工作是依据它的模板参数合成新的类型[注]。类型生成器产生的新类型一般作为生成器中嵌套的typedef出现。用类型生成器的主要目的是为了让复杂的类型表达式显得更简单些。比如boost::filter_iterator_generator:[b]
      template struct filter_iterator_generator { typedef iterator_adaptor, Value,Reference,Pointer,Category,Distance> type;}; [/b]
      看起来可真够复杂的。但现在生成一个合适的filter iterator可就容易多了,只需要写:[b]
      boost::filter_iterator_generator::type [/b]
      就行了。对象生成器
      对象生成器是一种函数模板,依据其参数产生新的对象。可以把它想象成泛型化的构造函数。有些情况下,欲生成的对象的精确类型很难甚至根本无法表示出 来,这时对象生成器可就管用了。对象生成器的优点还在于它的返回值可以直接作为函数参数,而不像构造函数那样只有在定义变量时才会调用。Boost和标准 库中用到的对象生成器大多都加了个前缀make_,比如std::make_pair(const T&, const U&)。
      看看下面的例子:[b]
      struct widget { void tweak(int);};std::vector widget_ptrs; [/b]
      通过把两个标准的对象生成器bind2nd和mem_fun合用,我们可以很轻松地tweak所有的widget:[b]
      void tweak_all_widgets1(int arg){ for_each(widget_ptrs.begin(), widget_ptrs.end(), bind2nd(std::mem_fun(&widget::tweak), arg));} [/b]
      如果不用对象生成器,上面的函数可能就得这样来实现:[b]
      void tweak_all_widgets2(int arg){ for_each(struct_ptrs.begin(), struct_ptrs.end(), std::binder2nd >( std::mem_fun1_t(&widget::tweak), arg));} [/b]
      表达式越复杂,就越需要缩短这些冗长的类型说明,对象生成器的好处也就越能显现。策略类
      策略类就是用来传递行为的模板参数。标准库中的std::allocator就是策略类,把内存管理的行为应用到标准容器中。
      Andrei Alexandrescu在他的文章中对策略类进入了全面而深入的分析,他写道:
      “策略类精确地反映了设计时的抉择。他们要么从其它类中继承,要么包含在其它类中。策略类在同样的句法结构上提供了不同的策略。使用策略的类把它用到的每一个策略都作为模板参数,这样,用户就可以自由地选择需要使用的策略。
      策略类的强大在于它们能够自由地组合在一起。通过把策略类作为模板参数的办法来组合多种策略,代码量与使用的策略数只成线性关系。”
      Andrei认为策略类的强大源于其小粒度和正交性。Boost在迭代适配器库中的策略类运用可能淡化了这一卖点。在这个库中,所有已适配的迭代器的行为都放在一个策略类里面。其实,Boost并不是开先河者。std::char_traits就是一个策略类,它决定了std::basic_string的行为,尽管它的名字叫traits而不叫policy。
      注:因为C++缺少模板化的typedef,类型生成器可以作为其替代方案。
    展开全文
  • 1969年第一台可编程控制器产生后,经过30多年发展,现在可编程控制器已经成为最重要、最可靠、应用场合最广泛工业控制微型计算机。可编程控制器应用于广播发射机可实现广播发射机自动开关机及采集并监控发射机...
  •  AVR嵌入式单片机具有丰富硬件、软件资源,其中串行I2C接口满足很多应用场合的要求,两个AVR单片机通过I2C总线直接连接就可实现单片机相互通信;AVR单片机还可以和任何具有I2C总线接口外设直接连接而无须...
  •  AVR嵌入式单片机具有丰富硬件、软件资源,其中串行I2C接口满足很多应用场合的要求,两个AVR单片机通过I2C总线直接连接就可实现单片机相互通信;AVR单片机还可以和任何具有I2C总线接口外设直接连接而无须...
  • 但当时作为首席执行官鲍尔默应该最代表微软公司观点,他说:“Microsoft.NET 代表了一个集合、一个环境、一个可以作为平台支持下一代Internet编程结构。”确实,这句话基本上简单扼要地表述了.NET外特性...

     

    .NET体系结构中,XML是各应用之间无缝接合的关键

    对于.NET到底是什么这个问题,有着各种各样的说法。但当时作为首席执行官的鲍尔默应该最能代表微软公司的观点,他说:“Microsoft.NET 代表了一个集合、一个环境、一个可以作为平台支持下一代Internet的可编程结构。确实,这句话基本上简单扼要地表述了.NET的外特性。

    .NET
    首先是一个环境。这是一个理想化的未来互联网环境,微软的构想是一个不再关注单个网站、单个设备与因特网相连的互联网环境,而是要让所有的计算机群、相关设备和服务商协同工作的网络计算环境。简而言之,互联网提供的服务,要能够完成更高程度的自动化处理。未来的互联网,应该以一个整体服务的形式展现在最终用户面前,用户只需要知道自己想要什么,而不需要一步步地在网上搜索、操作来达到自己的目的。这是一种理想,但的的确确是互联网的发展趋势所在。
    .NET
    谋求的是一种理想的互联网环境。而要搭建这样一种互联网环境,首先需要解决的问题是针对现有因特网的缺陷,来设计和创造一种下一代Internet结构。这种结构不是物理网络层次上的拓扑结构,而是面向软件和应用层次的一种有别于浏览器只能静态浏览的可编程Internet软件结构。因此.NET把自己定位为可以作为平台支持下一代Internet的可编程结构。

    NET
    的最终目的就是让用户在任何地方、任何时间,以及利用任何设备都能访问他们所需要的信息、文件和程序。而用户不需要知道这些东西存在什么地方,甚至连如何获得等具体细节都不知道。他们只需发出请求,然后只管接收就是了,而所有后台的复杂性是完全屏蔽起来的。所以对于企业的IT人员来说,他们也不需要管理复杂的平台以及各种分布应用之间的工作是如何协调的。
    .NET Framework
    包括通用语言运行环境、Framework类库和Active Server Pages+有了理想目标和相应可编程Internet软件结构,.NET这样的一个协同计算环境的具体实现还必然需要一系列的软件产品支撑,因此微软的.NET还包括一个产品的集合。这个集合包含以下组成部分:
    .NET
    平台开发新型的互动协作软件提供了一个先进的体系结构模型。 .NET系列产品和服务如MSN.NETOFFICE.NETVisual Studio.NETbCentral.NET等。 第三方厂商的.NET服务建立在.NET平台和产品上的面向不同应用领域的具体服务。从上面对.NET的简单分析可以看出,在对新技术和IT产业的推动上,无论如何,微软还是功不可没的。但与此同时, 也可以推测出,如果.NET一旦成为事实,那么对于其他非应用软件厂商而言,可能会产生巨大的竞争压力。

    .NET
    的技术特征

    .NET
    包括4个重要特点,一是软件变服务,二是基于XML的共同语言,三是融合多种设备和平台,四是新一代的人机界面。这四个特点基本上覆盖了.NET的技术特征。

    软件变服务

    史蒂夫·鲍尔默在谈到软件服务时说道,今天的软件产品仅仅是一张光盘,用户购买软件,亲自安装、管理和维护。但是软件服务是来自因特网的服务,它替用户安装、更新和跟踪这些软件,并让它们和用户一同在不同的机器间漫游。它为用户存储自己的信息和参考资料。这些就是软件和软件服务各自不同的风格。”Orchestration可视化编程工具产生基于XMLXLANG代码,它和BizTalk服务器、.NET Framework,以及Visual Studio.NET都曾是Windows DNA 2000战略的重要部分。

    伴随着ASP产业的兴起,软件正逐渐从产品形式向服务形式转化,这是整个IT行业的大势所趋。在.NET中,最终的软件应用是以Web服务的形式出现并在Internet发布的。Web服务是一种包装后的可以在Web上发布的组件,.NET通过WSDL协议来描述和发布这种Web服务信息,通过DISCO协议来查找相关的服务,通过SOAP协议进行相关的简单对象传递和调用。



    微软的.NET战略意味着:微软公司以及在微软平台上的开发者将会制造服务,而不是制造软件。在未来几年之内,微软将陆续发布有关.NET的平台和工具,用于在因特网上开发Web服务。那时,工作在.NET上的用户、开发人员和IT工作人员都不再购买软件、安装软件和维护软件。取而代之的是,他们将定制服务,软件会自动安装,所有的维护和升级也会通过互联网进行。

    基于XML的共同语言
    XML
    是从SGML语言演化而来的一种标记语言。作为元语言,它可以定义不同种类应用的数据交换语言。在.NET体系结构中,XML作为一种应用间无缝接合的手段,用于多种应用之间的数据采集与合并,用于不同应用之间的互操作和协同工作。

    具体而言,.NET通过XML语言定义了简单对象访问协议(SOAP)、Web服务描述语言(WSDL)、Web服务发现协议(DISCO)。SOAP协议提供了在无中心分布环境中使用XML交换结构化有类型数据的简单轻量的机制。WSDL协议定义了服务描述文档的结构,如类型、消息、端口类型、端口和服务本身。DISCO协议定义了如何从资源或者资源集合中提取服务描述 文档、相关服务发现算法等。
    融合多种设备和平台
    随着Internet逐渐成为一个信息和数据的中心,各种设备和服务已经或正在接入和融入Internet,成为其中的一部分。.NET谋求与各种Internet接入设备和平台的一体化,主要关注在无线设备和家庭网络设备及相关软件、平台方面。

    新一代的人机界面

    新一代人机界面主要体现在智能与互动两个方面。.NET包括通过自然语音、视觉、手写等多种模式的输入和表现方法;基于XML的可编辑复合信息架构——通用画布;个性化的信息代理服务;使机器能够更好地进行自动处理的智能标记等技术。

     

     

     看了这么久,若觉得有点累,可以到找一下音乐或电影网站放松一下心情,大家可以到百度影集(http://www.baidumovies.com/)这个网站看一下有没有自己喜欢的电影或电视剧或娱乐信息,这个网站信息更新比较快,电影也较多,目前收藏有20000多部国外内电影或电视剧,免费提供.网站没有任何烦人的弹出或浮动广告。

     

    转载于:https://www.cnblogs.com/BlogNetSpace/articles/1563616.html

    展开全文
  • 英文原文:http://www.boost.org/more/generic_programming.html1、何谓泛型编程泛型编程(Generic Programming)关注于产生通用软件组件,让这些组件在不同的应用场合很容易地重用。在C++中,类模板和函数...
    英文原文:http://www.boost.org/more/generic_programming.html
    1、何谓泛型编程

    泛型编程(Generic Programming)关注于产生通用的软件组件,让这些组件在不同的应用场合都能很容易地重用。在C++中,类模板和函数模板是进行泛型编程极为有效的机制。有了这两大利器,我们在实现泛型化的同时,并不需要付出效率的代价。

    作为泛型编程的一个简单例子,让我们看一下在C库中如何让memcpy()函数泛型化。一种实现方法可能是这样的:

        void* memcpy(void* region1, const void* region2, size_t n)
        {
            const char* first = (const char*)region2;
            const char* last = ((const char*)region2) + n;
            char* result = (char*)region1;
            while (first != last)
                *result++ = *first++;
            return result;
        }
            

    这个memcpy()函数已经在一定程度上进行了泛型化,采取的措施是使用void*,这样该函数就可以拷贝不同类型的数组。但如果我们想拷贝的数据不是放在数组里,而是由链表来存放呢?我们能不能扩展这个概念,让它可以拷贝任意的序列?看看memcpy()的函数体,这个函数对传入的序列有一个_最小需求_:它需要用某种形式的指针来遍历这个序列;访问指针正指向的元素;把元素写到目的地;比较指针以判断何时停止拷贝。C++标准库把这样的需求进行分组,称之为概念(concepts)。在这个例子中就有输入迭代器(对应于region1)和输出迭代器(对应于region2)这两个概念。

    如果我们把memcpy()用函数模板重写,使用输入迭代器和输出迭代器作为模板参数来描述对序列的需求,我们就可以写出一个具有较高重用性的copy()函数:

        template <typename InputIterator, typename OutputIterator>
        OutputIterator
        copy(InputIterator first, InputIterator last, OutputIterator result)
        {
            while (first != last)
                *result++ = *first++;
            return result;
        }
            

    使用这个泛型的copy()函数,我们可以拷贝各种各样的序列,只要它满足了我们指定的需求。对外提供了迭代器的链表,比如std::list,也可以通过我们的copy()函数来拷贝:

        #include <list>
        #include <vector>
        #include <iostream>
        int main()
        {
            const int N = 3;
            std::vector<int> region1(N);
            std::list<int> region2;
            
            region2.push_back(1);
            region2.push_back(0);
            region2.push_back(3);
            
            std::copy(region2.begin(), region2.end(), region1.begin());
            
            for (int i = 0; i < N; ++i)
                std::cout << region1[i] << " ";
            std::cout << std::endl;
        }
            

    2、何谓概念?

    概念就是需求的集合,这些需求可以包含有效表达式、相关类型、不变性,以及复杂度保证。满足概念中所有需求的类型,称之为此概念的一个样例。一个概念可以是对别的概念的扩展,称之为概念的细化。

        * 有效表达式:任意的C++表达式。若某类型是概念的一个样例,那么把该类型的一个对象代入此表达式中,该表达式必能通过编译。
        * 相关类型:与样例相关的一些类型,它们和样例共同出现在一个或多个有效表达式中。如果样例类型是自定义类型,则相关类型可以由类定义中所嵌套的一些typedef来访问。相关类型经常也通过traits类来访问。
        * 不变性:对象的一些运行时特征,必须为真。所有用到这个对象的函数,都必须保持这种特征。不变性通常以前置条件和后置条件的形式出现。
        * 复杂度保证:对概念中的有效表达式执行所需时间或资源所做的限制。

    C++标准库中所使用的概念在SGI STL网站上有详细的文档说明。
    3、Traits

    traits类为访问编译时实体(类型、整数常量,或者地址)的相关信息提供了一条途径。比如,类模板std::iterator_traits<T>看起来是这个样子:

        template <class Iterator>
        struct iterator_traits {
            typedef ... iterator_category;
            typedef ... value_type;
            typedef ... difference_type;
            typedef ... pointer;
            typedef ... reference;
        };
            

    该traits的value_type可以让泛型代码得知该迭代器所“指向”的是何种类型的数据;而iterator_category对迭代器的能力进行分类,针对不同类型的迭代器我们选择与之适应的最高效的算法。

    traits模板有一个很重要的特点:它们是非侵入的(non-intrusive)。我们可以为任何类型提供相关信息,不管它是内建的类型,还是第三方的库中提供的类型。为了给某一特定类型指定traits,一般采用部分特化或者全特化traits模板的方式。

    欲更深入的了解std::iterator_traits,可以参阅SGI提供的资料。std::numeric_limits<T>也采用了traits技术,提供表示各内建数值类型取值范围的常量值。
    4、标记分派

    另外有一种技术经常与traits合用,那就是标记分派。它依据类型的属性,通过函数重载进行分派。一个很好的例子就是std::advance()函数。这个函数的功能是将一个迭代器递增n次,对于不同类型的迭代器可以有各自优化的实现方法。如果是随机访问迭代器(可以以任意的距离前后跳转),advance()函数可以用i+=n来实现,既简单又高效,只需要常量时间。而其它的迭代器必须一步一步地递增,需要线性的时间复杂度。如果是双向迭代器,n就可能为负值,因此必须判断对迭代器到底是增还是减。

    标记分派和traits类的联系很紧密。分派所依据的属性(在这个例子中是iterator_category)一般都是通过traits类来取得。主advance()函数从iterator_traits中获得对应于该iterator的iterator_category,然后调用重载过的advance_dispach()函数。编译器依据作为参数传给advance_dispach()的iterator_category,选择合适的重载版本。标记只是一个极其简单的类,它的唯一任务就是为标记分派或者其它类似技术传递必要的信息。

        namespace std {
          struct input_iterator_tag { };
          struct bidirectional_iterator_tag { };
          struct random_access_iterator_tag { };


          namespace detail {
            template <class InputIterator, class Distance>
            void advance_dispatch(InputIterator& i, Distance n, input_iterator_tag) {
              while (n--) ++i;
            }


            template <class BidirectionalIterator, class Distance>
            void advance_dispatch(BidirectionalIterator& i, Distance n,
               bidirectional_iterator_tag) {
              if (n >= 0)
                while (n--) ++i;
              else
                while (n++) --i;
            }


            template <class RandomAccessIterator, class Distance>
            void advance_dispatch(RandomAccessIterator& i, Distance n,
               random_access_iterator_tag) {
              i += n;
            }
          }


          template <class InputIterator, class Distance>
          void advance(InputIterator& i, Distance n) {
            typename iterator_traits<InputIterator>::iterator_category category;
            detail::advance_dispatch(i, n, category);
          }
        }
            

    5、适配器

    适配器是一种类模板,建立在其它类型之上,提供新的接口或者行为。标准库中就使用了适配器,比如std::reverse_iterator通过反转迭代器的递增/递减行为,适配了迭代器,还有std::stack,通过适配标准容器,提供一个简单的堆栈接口。

    在这里可以找到标准库中所用适配器的深入阐述。
    6、类型生成器

    类型生成器的工作是依据它的模板参数合成新的类型[注]。类型生成器产生的新类型一般作为生成器中嵌套的typedef出现。用类型生成器的主要目的是为了让复杂的类型表达式显得更简单些。比如boost::filter_iterator_generator:

        template <class Predicate, class Iterator,
            class Value = complicated default,
            class Reference = complicated default,
            class Pointer = complicated default,
            class Category = complicated default,
            class Distance = complicated default
                 >
        struct filter_iterator_generator {
            typedef iterator_adaptor<
                Iterator,filter_iterator_policies<Predicate,Iterator>,
                Value,Reference,Pointer,Category,Distance> type;
        };
            

    看起来可真够复杂的。但现在生成一个合适的filter iterator可就容易多了,只需要写:

        boost::filter_iterator_generator<my_predicate,my_base_iterator>::type
            

    就行了。
    7、对象生成器

    对象生成器是一种函数模板,依据其参数产生新的对象。可以把它想象成泛型化的构造函数。有些情况下,欲生成的对象的精确类型很难甚至根本无法表示出来,这时对象生成器可就管用了。对象生成器的优点还在于它的返回值可以直接作为函数参数,而不像构造函数那样只有在定义变量时才会调用。Boost和标准库中用到的对象生成器大多都加了个前缀make_,比如std::make_pair(const T&, const U&)。

    看看下面的例子:

        struct widget {
          void tweak(int);
        };
        std::vector<widget *> widget_ptrs;
            

    通过把两个标准的对象生成器bind2nd和mem_fun合用,我们可以很轻松地tweak所有的widget:

        void tweak_all_widgets1(int arg)
        {
           for_each(widget_ptrs.begin(), widget_ptrs.end(),
              bind2nd(std::mem_fun(&widget::tweak), arg));
        }
            

    如果不用对象生成器,上面的函数可能就得这样来实现:

        void tweak_all_widgets2(int arg)
        {
           for_each(struct_ptrs.begin(), struct_ptrs.end(),
              std::binder2nd<std::mem_fun1_t<void, widget, int> >(
                  std::mem_fun1_t<void, widget, int>(&widget::tweak), arg));
        }
            

    表达式越复杂,就越需要缩短这些冗长的类型说明,对象生成器的好处也就越能显现。
    8、策略类

    策略类就是用来传递行为的模板参数。标准库中的std::allocator就是策略类,把内存管理的行为应用到标准容器中。

    Andrei Alexandrescu在他的文章中对策略类进入了全面而深入的分析,他写道:

    “策略类精确地反映了设计时的抉择。他们要么从其它类中继承,要么包含在其它类中。策略类在同样的句法结构上提供了不同的策略。使用策略的类把它用到的每一个策略都作为模板参数,这样,用户就可以自由地选择需要使用的策略。

    策略类的强大在于它们能够自由地组合在一起。通过把策略类作为模板参数的办法来组合多种策略,代码量与使用的策略数只成线性关系。”

    Andrei认为策略类的强大源于其小粒度和正交性。Boost在迭代适配器库中的策略类运用可能淡化了这一卖点。在这个库中,所有已适配的迭代器的行为都放在一个策略类里面。其实,Boost并不是开先河者。std::char_traits就是一个策略类,它决定了std::basic_string的行为,尽管它的名字叫traits而不叫policy。

    注:因为C++缺少模板化的typedef,类型生成器可以作为其替代方案。
     
    展开全文
  • 1969年第一台可编程控制器产生后,经过30多年发展,现在可编程控制器已经成为最重要、最可靠、应用场合最广泛工业控制微型计算机。可编程控制器应用于广播发射机可实现广播发射机自动开关机及采集并监控发射机...
  • Vector(向量)是 java.util 包中的一个类,该类实现了类似动态数组的功能。向量和数组相似,都可以保存一组数据(数据列表)。但是数组的大小是固定的,一旦指定,就不...向量和数组分别适用于不同的场合,一般来说,下...
  • Vector(向量)是 java.util 包中的一个类,该类实现了类似动态数组的功能。向量和数组相似,都可以保存一组数据(数据列表)。但是数组的大小是固定的,一旦指定,就不...向量和数组分别适用于不同的场合,一般来说,下...
  • Vector(向量)是 java.util 包中的一个类,该类实现了类似动态数组的功能。向量和数组相似,都可以保存一组数据(数据列表)。但是数组的大小是固定的,一旦指定,就不...向量和数组分别适用于不同的场合,一般来说,下...
  • Vector(向量)是 java.util 包中的一个类,该类实现了类似动态数组的功能。向量和数组相似,都可以保存一组数据(数据列表)。但是数组的大小是固定的,一旦指定,就不改变,而...向量和数组分别适用于不同的场合,一...
  • vector(向量)是 java.util 包中的一个类,该类实现了类似动态数组的功能。向量和数组相似,都可以保存一组数据(数据列表)。但是数组的大小是固定的,一旦指定,就不...向量和数组分别适用于不同的场合,一般来说,下...
  • 在许多应用场合,如大型设备中板卡,比较适合采用标准FPGA编程电路。但是对于便携式设备的应用场合,采用标准电路联系FPGA与CPU需要消耗资源太多。许多DSP芯片只有2个通用I/O引脚,所以如果只使用1~2个引脚...
  • 该资料《TCP/IP网络互联技术(卷3):客户-服务器编程应用(Windows套接字版)》源代码见: http://download.csdn.net/detail/fksec/4639930 TCP/IP网络互联技术(卷3):客户-服务器编程应用(Windows套接字...
  • 单总线芯片可以使得硬件结构非常简单,特别适合应用在对于距离远、节点分布多的场合,如粮仓温度检测,大棚温室温度监控等。本文给出的设计通用性好,可以方便地移植到其他应用场合。  1 Dsl8b20编程简介  每...
  • 8.27 各服务器类型所适用的场合 83 8.28 服务器类型小结 84 8.29 重要问题——服务器死锁 85 8.30 其他的实现方法 85 8.31 小结 85 深入研究 86 习题 86 第9章 循环的、无连接服务器(UDP) 87 9.1 引言 87 ...
  • 因此我打算讨论一下有关时间话题,尝试着深入理解Linux系统中C语言编程时间问题。主要内容如下:第1部分是应用程序中时间问题。有三个方面:程序计时需要;获取当前时间;定时器。第2部
  • 摘要:LED 显示屏设计一般采用单片机控制,文章介绍了应用编程器件实现显示部分硬件扫描控制一种方法,从而能够将软件处理与硬件扫描分离开来,使得软件设计更为方便灵活。  LED 大屏幕显示屏可广泛应用于...
  • 摘要:LED 显示屏设计一般采用单片机控制,文章介绍了应用编程器件实现显示部分硬件扫描控制一种方法,从而能够将软件处理与硬件扫描分离开来,使得软件设计更为方便灵活。  LED 大屏幕显示屏可广泛应用于...
  • 泛型编程

    2013-04-27 11:34:00
    众所周知,C++,具有面向对象的编程能力。然而C++不仅是一个面向对象程序语言,它还使用与泛型编程(Generic ... 泛型编程关注与产生通用软件组件,让这些组件在不同的应用场合很容易重用。在C++中...
  • Java网络编程之UDP编程

    2019-12-07 16:16:25
    UDP协议不是面向连接的传输协议,不保证数据按照顺序到达,无重传机制,会丢包、收到重复包、乱序等,所以在数据可靠性要求很高的场合,一般采用TCP协议 尽管如此,UDP协议仍然应用广泛,例如DNS服务、DHCP服务、网络音...
  • Boost中泛型编程技术

    千次阅读 2007-03-31 14:03:00
    何谓泛型编程 泛型编程(Generic Programming)关注于产生通用软件组件,让这些组件在不同的应用场合很容易地重用。在C++中,类模板和函数模板是进行泛型编程极为有效机制。有了这两大利器,我们在实现泛型...
  • 多内核方法也有它自己优势和强项,因此没有理由证明这两种方法不融合出一种最佳方法。在要求高性能、低成本和最小功耗的应用场合,多线程是一种极具竞争力方案。
  • 可用在可靠性不是十分重要的场合.如短消息 广播信息等 适合应用的情况有一下几种: 网络数据大多为短消息 拥有大量的客户端 对数据安全性无特殊要求 网络负担非常重,但对响应速度要求高. 2 UDP工作原理 UDP客户端...
  • 查找的应用

    2021-05-15 19:41:16
    1、掌握各种查找方法及适用场合,并在解决实际问题时灵活应用。 2、增强上机编程调试能力。 二、问题描述: 1.分别利用顺序查找和折半查找方法完成查找。 有序表(3,4,5,7,24,30,42,54,63,72,87,95) 输入示例: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 412
精华内容 164
关键字:

编程能应用的场合