=================================版权声明=================================

版权声明:本文为博主原创文章 未经许可不得转载 

请通过右侧公告中的“联系邮箱(wlsandwho@foxmail.com)”联系我

未经作者授权勿用于学术性引用。

未经作者授权勿用于商业出版、商业印刷、商业引用以及其他商业用途。                

本文不定期修正完善,为保证内容正确,建议移步原文处阅读。                                                               <--------总有一天我要自己做一个模板干掉这只土豆

本文链接:http://www.cnblogs.com/wlsandwho/p/4713311.html

耻辱墙:http://www.cnblogs.com/wlsandwho/p/4206472.html

=======================================================================

第九章 值类型

  值类型

    C++等价形式是.net类型名称的别名,用哪个都一样。

    所有值类型都是从System::ValueType继承。

    栈上存储

    不被垃圾回收

    直接访问没差别

    值类型有必要时可以当作对象使用

  结构

    结构是值类型而非引用类型。(例如表示坐标的点)

    .net结构的优点就是可以由其他语言来使用。

    不支持继承也不能作为基类

    能实现接口

    复制结构,是拷贝。

    结构成员不可以是引用类型,引用成员必须要垃圾回收。

    可嵌套定义。

    value struct Point

    {

      int x;

      int y;

    };

    value struct Person

    {

      String^ name;

      value struct Date { int yyyy,mm,dd;};

      Date dob;

    };

  枚举

    值类型 派生自System::Enum,System::ValueType。

    栈上

    枚举成员要有类型名称限定

    Format函数  String^ s=Enum::Format(WeekDay::typeid,w,"G");

    一定要有public或private,因为C++11标准产生C2644错误。

    枚举支持任何整数类型,节省内存

      public enum class Weekday:char

=======================================================================

第十章 操作符重载

  操作符重载

    C++/CLI的操作符重载限制比较大,主要是因为在.net中要兼容各语言。

      遵循CLS

      gcnew和delete不恩那个重载因为内存是由.net的运行时负责的。

    Equals函数

          virtual bool Equals(Object^ other) override
          {
              IntVal^ obj = dynamic_cast<IntVal^>(other);
              if (obj==nullptr)
              {
                  return false;
              }

      return value == obj->value;
          }

       重写Equals时也应该重写GetHashCode

    标准C++重写++时是前++和后++

    C++/CLI重写++时只有++

    转换操作符+精彩操作符

      static operator IntVal(int v)

      {

        return IntVal(v);

      }

      static IntVal operator+(IntVal liv,IntVal riv)

      {

        IntVal result(liv.value+riv.value);

        return result;

      }

 value struct IntVal
{
private:
int value;
public:
IntVal(int v):value(v){}
int getVal() { return value; } // IntVal operator+(IntVal rhs)
// {
// IntVal result(value + rhs.value);
// return result;
// } // IntVal operator+(int rhs)
// {
// IntVal result(value + rhs);
// return result;
// } // static IntVal operator+(int lhs, IntVal rhs)
// {
// IntVal result(lhs + rhs.value);
// return result;
// } static operator IntVal(int v)
{
return IntVal(v);
} static IntVal operator+(IntVal lhs, IntVal rhs)
{
IntVal result(lhs.value + rhs.value); return result;
} static bool operator==(IntVal lhs, IntVal rhs)
{
return lhs.value == rhs.value;
} static bool operator!=(IntVal lhs, IntVal rhs)
{
return !(lhs == rhs);
} virtual bool Equals(Object^ other) override
{
IntVal^ obj = dynamic_cast<IntVal^>(other);
if (obj==nullptr)
{
return false;
} return value == obj->value;
} static IntVal operator++(IntVal i)
{
i.value++;
return i;
}
};
 ref    struct LongVal
{
private:
long value;
public:
LongVal(long v) :value(v) {}
int getVal() { return value; } static operator LongVal^(long l)
{
return gcnew LongVal(l);
} static LongVal^ operator+(LongVal^ lhs, LongVal^ rhs)
{
LongVal^ result = gcnew LongVal(lhs->value + rhs->value); return result;
}
};
 int main(array<System::String ^> ^args)
{
//Console::WriteLine(L"Hello World");
IntVal one();
IntVal two();
IntVal three; three = one + two;
Console::WriteLine(three.getVal()); IntVal four;
four = two + ;
Console::WriteLine(four.getVal()); IntVal five;
five = + two;
Console::WriteLine(five.getVal()); IntVal somenum();
if (somenum == )
{
Console::WriteLine(L"somenum == 2");
} if (somenum != )
{
Console::WriteLine(L"somenum != 3");
} IntVal six(), seven();
if (!six.Equals(seven))
{
Console::WriteLine(L"six != seven");
} LongVal^ lone = gcnew LongVal();
LongVal^ ltwo = gcnew LongVal();
LongVal^ lthree = lone + ltwo;
Console::WriteLine(lthree->getVal()); return ;
}

=======================================================================

第十一章 异常处理

  类型转换

    safe_cast 转换失败抛出异常

    dynamic_cast转换失败返回空指针

  捕捉System::Exception派生类的对象

  C++

    构造函数 重载操作符——>异常在这些地方很有用

  C++/CLI

    传统C++异常

    C++/CLI异常

    SEH

  抛出异常

    

  形式

    try

    {

      if(a<0)

        throw gcnew ArgumentException(L"Test by WLS");

    }

    catch(ArgumentException^ ex)

    {  

      Console::WriteLine(L"Exception caught in Test by WLS");

      throw;

    }

    catch(Exception^)//捕捉所有异常 但会丢失所有异常信息

    {

    }

  创建自己的异常类型

    ref class WLSException:System::Exception

    {

      public:

        int ErrorNum;//自定义错误号

        WLSException(String^ msg,int num):Exception(msg),ErrorNum(num){}

    };

    使用时 throw gcnew WLSException(e->Message,666);

=======================================================================

第十二章  数组和集合

  用size_t比int要好

  泛型类型

    generic <typename T>

    ref class MyList

    {

    public:

      void Add(T num);

    }

  枚举器

    IEnumerator接口

    只能读取  修改还是要用常规循环

    迭代器模式  遍历任何集合  不保证顺序

    初始位置第一个之前

    MoveNext方法  移动到下一个元素,没有就返回false

    Current属性  当前项

    Reset方法   重置到第一个之前

  托管数组

    所有的托管数组都继承自System::Array

    array<类型,维度> handle_name

    托管堆

    垃圾回收

    索引从0开始 越界访问抛出异常

    arr1->Length  数组各维度的长度和

    arr1->GetLength(2)  第2维的长度

 array<Person^>^ arr3;//支持各种类型

 array<int>^ arr1 = { ,, };//C++风格

 array<int>^ arr2= gcnew array<int>() {,,};

 array<int>^ arr3 = gcnew array<int>() {,,};//为什么这个我的VS2015社区版不通过?  error C2748: 创建 托管 数组时必须提供数组大小或数组初始值设定项

 array<int, >^ arr1= gcnew array<int, >(,);//二维数组
Console::WriteLine(arr1->Length);
Console::WriteLine(arr1->GetLength());
Console::WriteLine(arr1->GetLength());
for (int i = ;i < arr1->GetLength();i++)
{
for (int j = ;j<arr1->GetLength();j++)
{
arr1[i,j] = i*j;//访问方式好独特,一个“[]”里用“,”分隔各个维度
}
} for (int i = ;i < arr1->GetLength();i++)
{
for (int j = ;j < arr1->GetLength();j++)
{
Console::WriteLine(arr1[i, j]);
}
}
 array<String^>^ arr = gcnew array<String^>(SIZE) {gcnew String(L"abc"), gcnew String(L"def")};//初始化

 array<String^>^ arrs = gcnew array<String^>(SIZE);
arrs[] = gcnew String(L"abc");
arrs[] = L"def";
 //多维数组
array<int, >^ arr1 = { {,,},{,,} };
for (int i = ;i < arr1->GetLength();i++)
{
for (int j = ;j < arr1->GetLength();j++)
{
Console::WriteLine(arr1[i, j]);
}
} array<int, >^ arr2 = gcnew array<int, >{ {, , }, { ,, }};
for (int i = ;i < arr2->GetLength();i++)
{
for (int j = ;j < arr2->GetLength();j++)
{
Console::WriteLine(arr2[i, j]);
}
}

怎么在多维数组中使用foreach来遍历其中的某一维呢?

例如遍历array<String^, 2>^ arr3 = gcnew array<String^, 2>{ {L"aa", L"bb", L"cc"}, { L"ee",L"ff",L"gg" }};的第二维的元素?

=======================================================================

第十三章  属性

  C++/CLI支持两种属性

    标量属性  通过取值赋值访问单个值  属性不一定是数据成员可以是导出值

    索引属性  使用[]来访问属性

  关键字 property

    构造函数里应该优先使用属性进行初始化而不是直接使用数据成员

    可以在属性里使用throw抛出异常

  自动实现属性

    property String^ Name;//默认实现get和set

  只读或只写属性

    property String^ Name

    {

      //只实现get或者set

      String^ g/set(){...}

    }

  继承、接口

    属性可以是virtual也可以是纯virtual的,可以在继承和接口中使用

 ref class CShape abstract
{
public:
virtual property double Area;
}; ref class CCricle:CShape
{
public: CCricle(double r) { m_nRadius = r; } virtual property double Area
{
double get() override
{
return Math::PI*m_nRadius*m_nRadius;
}
} void PrintArea()
{
Console::WriteLine(L"The Area is {0}",Area);
} private:
double m_nRadius;
}; int main(array<System::String ^> ^args)
{
CCricle^ oCricle = gcnew CCricle(4.0);
oCricle->PrintArea(); return ;
}

  索引属性

    默认属性

      类可以有多个索引器(索引属性),必须根据名称显示的使用。(下面的oBank->Balance[234567])

      名为default的索引属性可以在类对象上直接使用。(下面的CAccount^ pA = oBank[234567])

 #include "stdafx.h"

 using namespace System;
using namespace System::Collections::Generic; //////////////////////////////////////////////////////////////////////////
ref class CAccount
{
public:
CAccount(long lAccNum,double dBalance,double dLimit);
~CAccount(); property long AccountNumber
{
long get() { return m_lAccNumber; }
} property double Balance
{
double get() { return m_dBalance; }
} property double OverdraftLimit
{
double get() { return m_dLimit; }
void set(double dValue)
{
if (dValue<)
{
throw gcnew ArgumentException(L"Limit can not be negative");
} m_dLimit = dValue;
}
} private:
long m_lAccNumber;
double m_dBalance;
double m_dLimit;
}; CAccount::CAccount(long lAccNum, double dBalance, double dLimit)
{
Console::WriteLine(L"Account:Constructor"); if (lAccNum< || dLimit<)
{
throw gcnew ArgumentException(L"Bad Arguments to constructor");
} m_lAccNumber = lAccNum;
m_dBalance = dBalance;
m_dLimit = dLimit;
} CAccount::~CAccount()
{
}
//////////////////////////////////////////////////////////////////////////
ref class CBank
{
public:
CBank();
~CBank(); bool AddAccount(CAccount^ oAccount)
{
if (m_listAccounts->Contains(oAccount))
{
return false;
}
else
{
m_listAccounts->Add(oAccount);
} return true;
} bool RemoveAccount(CAccount^ oAccount)
{
if (m_listAccounts->Contains(oAccount))
{
m_listAccounts->Remove(oAccount); return true;
} return false;
} property double Balance[long]
{
double get(long lIndex)
{
for each (CAccount^ var in m_listAccounts)
{
if (var->AccountNumber==lIndex)
{
return var->Balance;
}
} throw gcnew ArgumentOutOfRangeException(L"No Such Account");
}
} property CAccount^ default[long]
{
CAccount^ get(long lIndex)
{
for each (CAccount^ var in m_listAccounts)
{
if (var->AccountNumber == lIndex)
{
return var;
}
} throw gcnew ArgumentOutOfRangeException(L"No Such Account");
}
}
private:
List<CAccount^>^ m_listAccounts;
}; CBank::CBank()
{
Console::WriteLine(L"Bank:Constructor"); m_listAccounts = gcnew List<CAccount^>();
} CBank::~CBank()
{
} int main(array<System::String ^> ^args)
{
CBank^ oBank = gcnew CBank(); CAccount^ oAccount1 = gcnew CAccount(, 10.0, 0.0);
CAccount^ oAccount2 = gcnew CAccount(, 110.0, 10.0);
CAccount^ oAccount3 = gcnew CAccount(, 1110.0, 110.0); oBank->AddAccount(oAccount1);
oBank->AddAccount(oAccount2);
oBank->AddAccount(oAccount3); CAccount^ pA = oBank[];
Console::WriteLine(L"The Account Number {0} has the banlance {1}.", pA->AccountNumber,oBank->Balance[]); return ;
}

(为什么我感觉我的代码写的有点问题,虽然可以跑?Balance属性真的这么写吗?)

=======================================================================

第十四章  委托和事件

  委托是特殊的类

    原理是将函数的执行委托给一个中间对象,调用具有特定签名的一个或者多个函数。

    C++/CLI的所有委托都是System::MulticastDelegate。

    关键字 delegate

      delegate double SomeOperating(double);

      只能调用托管类的成员函数(静态非静态都可以)。

        静态成员函数只需要传递函数地址

        非静态成员函数需要传递对象和函数地址

      委托创建好后不能改变调用的函数,但是可以重新gcnew一个新的,垃圾自动回收。

      调用委托可以使用invoke也可以使用委托的仿函数。

      MulticastDelegate使用Combine和Remove来操作调用列表。

      MulticastDelegate使用合并其他委托的方法来生成。

      MulticastDelegate的调用顺序由合并顺序决定。

      MulticastDelegate通常用不返回值的函数,但也可以返回值,一般是最后一个的结果。想要获得某个结果可以遍历委托列表。

 #include "stdafx.h"

 using namespace System;

 delegate double NumbericOp1(double);
delegate double NumbericOp2(double, double); ref class Ops
{
public:
static double Square(double dNum) { return dNum*dNum; }
static double Cube(double dNum) { return dNum*dNum*dNum; } double MultiAandB(double dNum1, double dNum2) { return dNum1*dNum2; }
}; int main(array<System::String ^> ^args)
{
NumbericOp1^ NOp1 = gcnew NumbericOp1(Ops::Square);//静态函数//编译通过了 double dTempNum1 = 10.0; Console::WriteLine(L"Square({0}) = {1}",dTempNum1,NOp1->Invoke(dTempNum1));
Console::WriteLine(L"Square({0}) = {1}", dTempNum1, NOp1(dTempNum1)); NOp1 = gcnew NumbericOp1(Ops::Cube);//静态函数//编译通过了 Console::WriteLine(L"Square({0}) = {1}", dTempNum1, NOp1->Invoke(dTempNum1));
Console::WriteLine(L"Square({0}) = {1}", dTempNum1, NOp1(dTempNum1)); //////////////////////////////////////////////////////////////////////////
double dTempNum2 = 2.0;
double dTempNum3 = 3.0; Ops^ objOps=gcnew Ops(); NumbericOp2^ NOp2;
NOp2 = gcnew NumbericOp2(objOps, &Ops::MultiAandB);//非静态函数 Console::WriteLine(L"multi({0},{1})={2}", dTempNum2,dTempNum3,NOp2->Invoke(dTempNum2,dTempNum3));
Console::WriteLine(L"multi({0},{1})={2}", dTempNum2, dTempNum3, NOp2(dTempNum2, dTempNum3)); return ;
}
 #include "stdafx.h"

 using namespace System;

 delegate void PrintSomething(int);

 delegate int DOperation(int);

 ref class CClient1
{
public:
static void Print(int nNum) { Console::WriteLine(L"CClient1 {0}",nNum); }
int DoubleNum(int nNum) { return nNum<<; }
}; ref class CClient2
{
public:
static void Print(int nNum) { Console::WriteLine(L"CClient2 {0}",nNum); }
int DDoubleNum(int nNum) { return nNum << ; }
}; int main(array<System::String ^> ^args)
{
PrintSomething^ PS1=gcnew PrintSomething(CClient1::Print);
PrintSomething^ PS2=gcnew PrintSomething(CClient2::Print);
PrintSomething^ PS3;
PS3+= PS1+PS2;
PS3(); Console::WriteLine(L"-------------");
PS3 += PS3+PS3;
PS3(); Console::WriteLine(L"-------------");
PrintSomething^ PS4;
PS4 = PS3 + PS3;
PS4(); Console::WriteLine(L"-------------");
PS4 -= PS3;
PS4(); CClient1^ oC1 = gcnew CClient1();
CClient2^ oC2 = gcnew CClient2(); DOperation^ DOp;
DOp = gcnew DOperation(oC1, &CClient1::DoubleNum)+gcnew DOperation(oC2,&CClient2::DDoubleNum); for each (DOperation^ dop in DOp->GetInvocationList())
{
Console::WriteLine(dop());
} return ;
}

  .net的事件

    发布-订阅 机制

    基于委托

      事件只能由声明它的类型引发

      客户端只能用+=和-=来增删事件处理函数,不能用=重置调用列表

    事件源声明委托

    事件接收者提供适当方法

    方法绑定到委托

    事件发生调用委托进而调用方法

 #include "stdafx.h"

 using namespace System;

 //////////////////////////////////////////////////////////////////////////
delegate void FristEventHandler(String^);
delegate void SecondEventHandle(String^); ref class EventSrc
{
public:
event FristEventHandler^ OnFirstEvent;
event SecondEventHandle^ OnSecondEvent; void RaiseOne(String^ msg) { OnFirstEvent(msg); }
void RaiseTwo(String^ msg) { OnSecondEvent(msg); }
};
//////////////////////////////////////////////////////////////////////////
ref class EventReceiver
{
public:
EventReceiver(EventSrc^ esrc)
{
if (esrc==nullptr)
{
throw gcnew ArgumentException(L"Must have event source");
} m_EventSrc = esrc; m_EventSrc->OnFirstEvent += gcnew FristEventHandler(this, &EventReceiver::DoforFirstEvent);
m_EventSrc->OnSecondEvent += gcnew SecondEventHandle(this, &EventReceiver::DoforSecondEvent);
} void RemoveHandler()
{
m_EventSrc->OnFirstEvent -= gcnew FristEventHandler(this, &EventReceiver::DoforFirstEvent);
} void DoforFirstEvent(String^ msg) { Console::WriteLine(L"[Eventreceiver] event one,message {0}", msg); }
void DoforSecondEvent(String^ msg) { Console::WriteLine(L"[Eventreceiver] event two,message {0}", msg); } private:
EventSrc^ m_EventSrc;
}; int main(array<System::String ^> ^args)
{
EventSrc^ src = gcnew EventSrc();
EventReceiver^ recvr = gcnew EventReceiver(src); src->RaiseOne(L"Hahaha");
src->RaiseTwo(L"blablabla"); Console::WriteLine();
recvr->RemoveHandler(); src->RaiseOne(L"Hahaha");
src->RaiseTwo(L"blablabla"); return ;
}

  标准事件 System::EventHandler

    签名  delegate void EventHandler(System::Object^ sender, System::EventArgs^ e)

    建议使用标准事件

      直接使用System::EventHandler

 #include "stdafx.h"

 using namespace System;

 //////////////////////////////////////////////////////////////////////////
ref class CCounter
{
public:
CCounter(int nLimit)
{
m_nCounter = ;
m_nLimit = nLimit;
} event EventHandler^ LimitReached; void Increment()
{
Console::WriteLine(L"Count:{0}",++m_nCounter); if (m_nCounter % m_nLimit==)
{
LimitReached(this, gcnew EventArgs());
}
} private:
int m_nCounter;
int m_nLimit;
}; //////////////////////////////////////////////////////////////////////////
ref class CObserver
{
public:
static void Callme(Object^ src, EventArgs^ args)
{
Console::WriteLine(L"Limit reached");
} void CallmeBaby(Object^ src, EventArgs^ args)
{
Console::WriteLine(L"Oh,Honey!");
} }; //////////////////////////////////////////////////////////////////////////
int main(array<System::String ^> ^args)
{
//////////////////////////////////////////////////////////////////////////
CCounter^ oCounter=gcnew CCounter(); //////////////////////////////////////////////////////////////////////////
oCounter->LimitReached += gcnew EventHandler(&CObserver::Callme); for (int i = ;i<;i++)
{
oCounter->Increment();
} //////////////////////////////////////////////////////////////////////////
//oCounter->LimitReached -= gcnew EventHandler(&CObserver::Callme);
////////////////////////////////////////////////////////////////////////// CObserver^ oObserver=gcnew CObserver(); oCounter->LimitReached += gcnew EventHandler(oObserver, &CObserver::CallmeBaby); for (int i = ;i < ;i++)
{
oCounter->Increment();
} return ;
}

=======================================================================

第十五章  .NET Framework类库

  鼓吹.NET的一章,泛泛草草的说了几页,意思大概就是之前的十四章都看完了,接着往下看吧,好戏才刚开始呢。

=======================================================================

第Ⅱ部分也没难度,只是容易忘、记不住。

=======================================================================

说说书上的错误吧

Page75 6.5 在类中使用常量

第一个小圆点· “它的值对于Card的所有实例来说都是4”,很显然英文拼错了,正确是“Car”

Page174 12.3.1 初始化
一共有三行代码,第二行的代码不能有(),应该改为array<int>^ intArray=gcnew array<int>{1,2,3};

Page207 14.2.2 使用MulticastDelegate

“而对于MutlcastDelegate,可使用……”中的英文显然拼错了,正确是“MulticastDelegate”

=======================================================================

再说说一点瑕疵

Page195 13.2.4 属性、继承和接口

在练习中给出的托管类定义,ref的前面是不需要public的,至少在这个例子和当前的教学上下文是不需要的。

=======================================================================

有空开始看第Ⅲ部分

C++/CLI——读书笔记《Visual C++/CLI从入门到精通》 第Ⅱ部分的更多相关文章

  1. C++/CLI——读书笔记《Visual C++/CLI从入门到精通》 第Ⅳ部分

    =================================版权声明================================= 版权声明:本文为博主原创文章 未经许可不得转载  请通过右 ...

  2. C++/CLI——读书笔记《Visual C++/CLI从入门到精通》 第Ⅰ部分

    =================================版权声明================================= 版权声明:本文为博主原创文章 未经许可不得转载  请通过右 ...

  3. 《利用python进行数据分析》读书笔记--第五章 pandas入门

    http://www.cnblogs.com/batteryhp/p/5006274.html pandas是本书后续内容的首选库.pandas可以满足以下需求: 具备按轴自动或显式数据对齐功能的数据 ...

  4. <<Java RESTful Web Service实战>> 读书笔记

    <<Java RESTful Web Service实战>> 读书笔记 第一章   JAX-RS2.0入门 REST (Representational State ransf ...

  5. 4 Visual Effects 视觉效果 读书笔记 第四章

    4   Visual Effects    视觉效果        读书笔记 第四章 Well, circles and ovals are good, but how about drawing r ...

  6. 《Visual C# 从入门到精通》第一章使用变量、操作符和表达式——读书笔记

    前言: 这个笔记是我个人总结,主要是熟练自己查看<Visual C# 从入门到精通>(第8版)这本书时,懵然起总结的想法,只是总结一些知识点,在工作项目会用得上,但是对毫无C#语言基础的, ...

  7. Angular学习笔记:Angular CLI

    定义 Angular CLI:The Angular CLI is a command line interface tool that can create a project, add files ...

  8. 认识CLR [《CLR via C#》读书笔记]

    认识CLR [<CLR via C#>读书笔记] <CLR via C#>读书笔记 什么是CLR CLR的基本概念 通用语言运行平台(Common Language Runti ...

  9. CLR基础之一---认识CLR [《CLR via C#》读书笔记]

    <CLR via C#>读书笔记 什么是CLR CLR的基本概念 通用语言运行平台(Common Language Runtime,简称CLR)是微软为他们的.Net虚拟机所选用的名称.这 ...

随机推荐

  1. c++之string.find(string)

    先来看一个例子吧: #include "iostream" #include "string" using namespace std; // 定义函数求str ...

  2. tomcat中server.xml配置详解

    Tomcat Server的结构图如下: 该文件描述了如何启动Tomcat Server <Server>     <Listener />     <GlobaNami ...

  3. Enum 枚举小结 java **** 最爱那水货

    import java.util.HashMap; import java.util.Map; /** * 收单行 大写首字母 和对应的编码<br/> * * ABC 农业银行<br ...

  4. 窗口之间的主从关系与Z-Order

    说明:这是本人2008年写的一篇旧文,从未公开发表过.其中除了一小段描述Window Mobile平台的内容已过时,大部分内容对于从事Win32开发的程序员还是很有参考价值的,也是对自己从事Windo ...

  5. Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  6. java内存模型-volatile

    volatile 的特性 当我们声明共享变量为 volatile 后,对这个变量的读/写将会很特别.理解 volatile 特性的一个好方法是:把对 volatile 变量的单个读/写,看成是使用同一 ...

  7. 一款开源且功能强大的C#甘特图控件.NET Winforms Gantt Chart Control

    甘特图在项目管理中非常重要,甘特图的思想比较简单,即以图示的方式通过活动列表和时间刻度形象地表示出任何特定项目的活动顺序与持续时间.它直观地表明任务计划在什么时候进行,及实际进展与计划要求的对比.管理 ...

  8. 免费的 Photoshop Apple Watch 原型设计素材

    大量的扁平化的苹果设备原型展示了响应式的 Web 设计.这是一组免费的 Photoshop Apple Watch 原型 PSD 设计素材,文件包括 iPhone.iPad. iMac 和 Macbo ...

  9. css居中完全指南(翻译)

    最近参加了百度的前端技术学院,任务4是要求一个元素在父元素中水平和垂直居中,提供的一篇文章对各种情况都进行了分析,很不错,英文也不是那么难懂,毕竟代码还是主体,翻译过来分享出来,翻译内容带有自己的理解 ...

  10. Python十六进制与字符串的转换

    电脑上装了Python2.7和3.3两个版本,平时运行程序包括在Eclipse里面调试都会使用2.7,但是由于某些原因在cmd命令行中输入python得到的解释器则是3.3, 一直没对此做处理,因为这 ...