科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件实例解析C++/CLI中的接口与泛型

实例解析C++/CLI中的接口与泛型

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

某些时候,让不相关的类分享一组公有成员,以便产生相同的行为,是非常有用的。

作者:谢启东编译 来源:天极开发 2007年11月12日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
泛型

  就像函数能用一个或多个类型表示符来定义一样,类型也可以这样来定义。假如有这样一种情况,某种类型建模了一个"数组",其可使用下标来访问每个元素,这样的类型往往被称为"向量",实现一个向量之后,可以保存一组int、一组double、或一组用户自定义类型的元素。然而,正是因为每种类型实现的代码对类型中的元素来说,都是唯一的,因此,可使用泛型机制来定义一个向量类型,并创建特定类型的实例。例10就是这样的一个例子。

  例10:

generic <typename T>
public ref class Vector
{
 int length;
 /*1*/ array<T>^ vector;
 public:
  property int Length
  {
   int get() { return length; }
   private:
    void set(int value) { length = value; }
  }
  /*2*/ property T default[int]
  {
   T get(int index) { return vector[index]; }
   void set(int index, T value) { vector[index] = value; }
  }
  Vector(int vectorLength, T initValue)
  {
   Length = vectorLength;
   vector = gcnew array<T>(Length);
   for (int i = 0; i < Length; ++i)
   {
    /*3*/ this[i] = initValue;
   }
   /*4*/ //for each (T element in vector)
   //{
    // element = initValue;
   //}
  }
  Vector(int vectorLength)
  {
   Length = vectorLength;
   vector = gcnew array<T>(Length);
   for (int i = 0; i < Length; ++i)
   {
    /*5*/ this[i] = T();
   }
  }
  Vector()
  {
   Length = 0;
   /*6*/ vector = gcnew array<T>(0);
  }
  ~Vector() //多余的
  {
   /*7*/ vector = nullptr;
  }
  virtual String^ ToString() override
  {
   String^ s = "[";
   int i;
   for (i = 0; i < Length - 1; ++i)
   {
    /*8*/ s = String::Concat(s, this[i], ":");
   }
   /*9*/ s = String::Concat(s, this[i], "]");
   return s;
  }
  virtual bool Equals(Object^ obj) override
  {
   if (obj == nullptr)
   {
    return false;
   }
   if (this == obj) //在测试自身吗?
   {
    return true;
   }
   /*10*/ if (GetType() == obj->GetType())
   {
    Vector<T>^ v = static_cast<Vector^>(obj);
    if (Length != v->Length) //是否向量有不同的长度?
    {
     return false;
    }
    for (int i = 0; i < Length; ++i)
    {
     /*11*/ //if (this[i] != v[i])
     if (this[i]->Equals(v[i]) == false)
     {
      return false;
     }
    }
    return true;
   }
   return false;
  }
  /*12*/ virtual int GetHashCode() override
  {
   return 0;
  }
};

  如同泛型函数一样,泛型的定义一般由generic <typename t1, ..., typename tn>打头,意思是通过tn引入了类型参数t1,这些参数的作用范围,可从类型定义的结束直到它们所依附的对象。在本例中,只有一个类型参数T。

  在标号1中可见,一个Vector是作为一个类型为T的元素数组存储的。

  在标号2中,定义了一个默认的索引属性,以便可用一个int下标值来访问一个Vector。当然了,在运行时,我们可以存取类型为T的元素,而不用管它实际上是什么类型。

  与其直接访问私有成员,倒不如通过公有属性来进行访问,比如说,用Length来取代length;使用下标来访问当前的Vector(标号3)时,我们使用了this[i]。在此,很有可能会想到使用for each循环来取代一般的老式for循环,如标号4,但是,在此使用for循环是行不通的。在for each循环中,通过命名在循环结构中的局部变量,可为每个元素都产生一个副本,也就是说,变量已经不是原来的元素了,因此,修改它的值不会改变元素的值。

  在标号5中,需要把每个元素设为默认值,幸运的是,标准C++要求每种类型都有一个默认的构造函数--甚至对不是类的类型也是这样,一般表示为类型名后紧跟空的圆括号。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章