## 无参数

我们都知道使用多线程最简单的方式是下面这样:

代码
void SomeMethod()
{
    
//do something
}

void CreateThread()
{
    Thread thread 
= new Thread(new ThreadStart(SomeMethod));
    thread.Start();
}
 
##一个参数
 但是如果要是想给SomeMethod方法传入参数的话,发现这种方法不好用了

 因为Thread类并不支持这样

 

但是为了解决这个问题,类库中提供了一个支持的代理

 ParameterizedThreadStart

 使用它可以支持传入一个参数.注意,是仅仅一个!!

使用以下方法实现

代码
void SomeMethod(object arg)
{
    
// 假如传的是string
    
// string argStr = (string)arg;
    
// do something
}

void CreateThread()
{
    Thread thread 
= new Thread(new ParameterizedThreadStart(SomeMethod));
    
string arg = "Hello World!";
    thread.Start(arg);
}

 

##多个参数

 但是假如有多个参数就遇到麻烦了,上述方法只允许一个参数.

我们有两种方法:

1. 新建一个内部类,包装所有的参数,然后传入这个内部类的一个实例,如下: 

 

代码
void SomeMethod(object myArgs)
{
    MyArgs args 
= (MyArgs)myArgs;
    
string str = args.HelloString;
    
//do something
}

void CreateThread()
{
    Thread thread 
= new Thread(new ParameterizedThreadStart(SomeMethod));
    MyArgs args 
= new MyArgs("Hello World!")
    thread.Start(args);
}

private class MyArgs
{
    
string helloString;

    
public string HelloString
    {
        
get { return helloString; }
        
set { helloString = value; }
    }

    MyArgs(
string helloString)
    {
        
this.helloString = helloString;
    }
}

 

 2. 调用方法需要使用的参数存在此方法的类中,代码示例如下:

代码
public class MyThreadHelper {
    
//要用到的属性,也就是我们要传递的参数
    private string helloString;

    
public string HelloString
    {
        
get { return helloString; }
        
set { helloString = value; }
    }

    
//包含参数的构造函数
    public MyThreadHelper(string helloString)
    {
        
this.helloString = helloString;
    }

    
//要丢给线程执行的方法,本处无返回类型就是为了能让ThreadStart来调用
    public void SomeMethod() 
    {
        
string helloString = this.helloString;
        
// do something
    }
}

void CreateThread()
{
    MyThreadHelper helper 
= new MyThreadHelper("Hello World!");
    Thread thread 
= new Thread(new ThreadStart(helper.SomeMethod));
    thread.Start();
}

 

3.  直接在ThreadStart构造函数中添加代理,这种方法不用考虑参数的个数 (感谢 qianlifeng)

 代码如下:

 

ThreadStart starter = delegate { SomeMethod(arg1, arg2, arg3); };
new Thread(starter).Start();

 

##结束
至此,多线程传不同个数(零到多个)参数都有了解决办法.

 

老子曰: 道生一 一生二 二生三 三生万物

 

posted @ 2010-03-31 16:32 张东杰 阅读(629) 评论(4) 编辑

1. 要使用库必须要先:

#include 库

 比如 #include <iostream>

        #include <cstring>

        #include <cmath>

 注意:这里后面没有分号";", 因为这里使用的是指令,系统库有对应的尖括号的文件,所以可以用尖括号

 

要使用自定义的库,也需要include进来,这里用引号,并且是文件全名

比如 #include "MyLib.h"

 

2. 使用其他库中的某一个函数或者变量要先

using 命名空间::函数

或者

using 命名空间::变量

 比如 using std::cout;

        using std::strcpy;

 注意:后面带分号";",因为是要执行的语句,而且即使是最普通的cout也需要using,这个和C#, Java不一样

 

 为了简便起见,一般使用

using namespace std;

 就可以使用已经#include了的std namespace下面的内容,除去不必要的书写很多using的麻烦

 

3. 基本类型转换 使用函数 static_cast<type>()

转换后的类型变量 = static_cast< 要转换的类型 >( 被转换的变量 );

 比如 double result = static_cast< double >( original );

 

 4. 接口可以实现可以分开写,也就是可以把定义都写在.h文件里,实现写在.cpp中

 不过.h文件也可以有实现,但是容易发生冲突,也不容易扩展

 在.h中定义的只是方法的原型,并且可以指名访问修饰符,public, private等

一个修饰符下面可以有若干个均使用此修饰符的定义

代码
// IntSet.h
class IntSet
{
public:
    IntSet(
void);
    
void insert(int);
    
bool IsEqual(IntSet);
    IntSet union2(IntSet, IntSet);
    IntSet incorporate2(IntSet, IntSet);
    
void print();

    
int get(int);
    
int getSize();

private:
    
const static int ORIGINAL_SIZE = 16;
    
int size;
    
int counter; //elements number
    int *elements; //elements

    
void moveArray(int *intint);
    
void copyArray(int *int *intint);    
};


 5. 给头文件中定义的变量赋值 只能为const常数 或者只声明不赋值

比如 const static int ORIGINAL_SIZE = 16;
       int size;

在实现的文件中不受此限(即全局变量或者局部变量)

可以 int size = 16;

 

6.  在类中声明的变量是类专属的,称为"类成员变量",一般在.h的class中

在.cpp 文件中所有函数外声明的变量称为"全局变量",是文件访问级别的.

也就是说 全局变量在一个文件中定义,就可以在所有文件中使用.

这个是要十分小心的,因为实例化了很多相同类之后,每个实例使用这个全局变量都是同一个,而不是"隔离"的

如果想要每个实例都有自己的一个拷贝,那么就要定义在class中,声明类成员变量

 

7.  想要使用随机数可以使用如下方法

       #include <cstdlib> // contains function prototype for rand 

       using std::rand;

 

   则 rand() % 6 可以得到0 - 5的随机数

 注意:这里得到的伪随机数顺序是固定不变的,因为使用了相同的种子(seed),为了测试才这样设计,默认种子为1

 若要得到相对比较随机的数,可以在此之前使用 srand(time(0)); 或者 srand(time(NULL));得到随机的种子,由此得到随机的数

 

 8. 声明函数的时候无参数,可以不写,也可以写void明确指出

比如 void myFunction(void)

 声明函数的时候还可以为参数指定默认值

比如 void myFunction(int length = 1, int width = 1, int height = 1)

这样在调用函数 myFunction(1, 2) 的时候height的默认值就会赋为 1

注意:当函数有多个参数的时候,可以只传入前面的几个参数,后面的可以省略,不会编译出错,这和Java和C#不同

 

9. 用如下方式声明的 char *s1 = "Hello World!"; 中的单个字符是不可修改的

因为它指向的是字符串字面量(String Literal),是静态对象.

 想要声明一个可以修改单字符的指针可以使用如下方法,将它分配到堆上.

char *p = malloc(sizeof("Hello World!"));
strcpy(p,
"Hello World!");

//或者也可以用非ANSI C的库函数
char *p = strdup("Hello World!");


 

10.  注意string定义在<string>中

 要想打印出string

 比如 string str1 = "Hello World!";

        cout << str1;

 则要使用 #include <string> 否则会提示没有重载 << ,编译不通过

 

 

 

posted @ 2010-03-27 13:28 张东杰 阅读(151) 评论(2) 编辑