学习杂记(2)

来源:互联网 发布:网页js文件作用 编辑:程序博客网 时间:2024/05/16 10:09

(1)LPCTSTR Convert::StdStringToLPCTSTR(string srcString)

 LPCTSTR lpzsString=(LPCTSTR)srcString.c_str();
 return lpzsString;
}
这个函数的参数不对,如《C++Gothas》所说,当调用该函数时,会发生字符串拷贝,并
产生一个函数内的局部栈对象,而lpzsString指向该对象。
所以应该为LPCTSTR Convert::StdStringToLPCTSTR(const std::string& srcString)

(2)关于union的大小(网摘)

union DATE
{
    char a;
    int i[5];
    double b;
};
DATE max;
cout<< sizeof(max) << endl; (24)
①联合就是一个结构
②它的所有成员相对于基地址的偏移量都为0
③此结构空间要大到足够容纳最“宽”的成员
④其对齐方式要适合于联合中所有类型的成员
该结构要放得下int i[5]必须要至少占4×5=20个字节。如果没有double的话20个字节够用了,
此时按4字节对齐。但是加入了double就必须考虑double的对齐方式,double是按照8字节对齐的,
所以必须添加4个字节使其满足8×3=24,也就是必须也是8的倍数,这样一来就出来了24这个数字。
综上所述,最终联合体的最小的size也要是所包含的所有类型的基本长度的最小公倍数才行。


typedef long Align;
union header {
    struct {
        union header *ptr;
        unsigned size;
    } s;
    Align x;
}
这里的Align强迫分配的结构体按long的长度对齐

(3)预编译操作符
##连接符
#相当于添加双引号
#@添加单引号

#define tem1(filename) string(##filename"_temp")
#define tem2(filename) string(#filename"_temp")
#define tem3(filename) #@filename

void main()
{
    tem1("abc");   //"abc_temp"
    tem2(abc);     //"abc_temp"
    tem2("abc");   //""abc"_temp"
    tem3(a);       //'a'   

    string str = "abc";
    tem2(str);
    char aChar = 'a'
    tem3(aChar);
      
    tem1(str);   //Error
   
    tem1(abc);   //Error   
    tem3(ab);    //Unknown result
}

(4)和C++相比C#语法使用的主要不同:
1、get和set方法(属性访问器)
class a
{
 string m_str;
 public string str
 {
  get
  {
   return m_str;
  }
  set
  {
   if(m_str != value)
    m_str = value;
  }
 }
}

2、函数参数:out、ref、params
(1)ref:引用;对于引用类型的变量用null判别
(2)调用包含out参数的函数时,参数不用先初始化,作用同ref;
(3)如果形参表包含了数组型参数,则必须位于参数表的最后;

3、使用static readonly int name = 111 代替const、define;

4、代表delegate,相当于函数指针
delegate int MyDelegate(); //声明一个代表
public class MyClass
{
 public int InstanceMethod ()
 {
  Console.WriteLine("Call the instance method.");
  return 0;
 } 
}
public class Test

 MyClass p = new MyClass();
 // 将代表指向非静态的方法InstanceMethod
 MyDelegate d = new MyDelegate(p.InstanceMethod);
 // 调用非静态方法
 d(); 
}
   
5、virtual、overrid、new、abstract、sealed
(1)多态性可以分为编译时(通过重载方法和运算符实现)和运行时(通过虚成员实现)
class A
{
 public void F() { Console.WriteLine("A.F"); }
 public virtual void G() { Console.WriteLine("A.G"); }
}
class B: A
{
 new public void F() { Console.WriteLine("B.F"); }  //可以不用new,但会产生警告
 public override void G() { Console.WriteLine("B.G"); }
}
B b = new B();
A a = b; //note:可以被实例化,不是抽象类
a.F(); //A.F
b.F(); //B.f
a.G(); //B.G
b.G(); //B.g

(2)只能在抽象类中声明抽象方法,抽象方法同时是虚方法(事实上是一个新的虚方法);但抽象类
不一定只包括抽象方法,它不能同时是密封类;
(3)密封类为了防止被继承,如果密封类实例中存在虚成员函数,该成员函数可以转化为非虚的函数,
修饰符virtual不再生效;相应地,密封方法是防止派生类中对该类的重载;
(4)除了abstract和override能同时使用外,static,virtual,override和abstract中任意两个不能同时出现;

6、checked和unchecked,检查整数是否越界,可以在预编译中定义

7、is && as
都会发生一次类型转换,is返回bool,as返回新类型或null;注意如果需要转换类型,则用as

8、索引器index
class IP
{
 private IPAddress[] m_arrayIPs;
 public IPAddress this[int nIndex]
 {
  get
  {
   return m_arrayIPs[nIndex];
  }
 }
}

名称空间别名限定符的引入

9、命名空间别名限定符::
using AC = A.Collections;
using BC = B.Collections;
class Program
{
   static void main()
   {
       AC::ArrayList list = new AC::ArrayList();  
   }
}

10、接口和映射


原创粉丝点击