C++CLI——4数组、泛型、集合与属性

17 篇文章 0 订阅

C++CLI——4数组、泛型、集合与属性

C++数组

在c++中,数组的大小必须在编译时确定,并且将数组传递给函数时,传递的只是数组起始地址,所以要想办法连同数组大小一同传递给函数。

int arr[4] = { 1,2,3,4 };
int arr1[] = { 1,2,3,4 };
int arr2[2][3] //多维数组

动态创建数组

C++中直接声明数组需要明确数组的大小,但是可以使用new来动态创建数组,虽然这样数组也有固定的大小,只是在运行期间可以确定需要多少元素后再创建制定大小数组。

int* pa = new int[size];//size为运行时确定
delete [] pa;//不用时要释放

C++/CLI泛型

C#中具有泛型类型,C++/CLI中也具有泛型类型。

generic <typename T>
ref class Mylist
{
public:
	void Add(T obj);
	T GetAtIndex(int idx);
};

//使用时制定泛型类型
Mylist<String^>^ lists = gcnew Mylist<String^>();

C++中的泛型模板和.net中的泛型虽然功能很相似,但是工作方式完全不同,所以在C++/CLR中都得到了支持。两者主要的不同之处有:

  1. 模版是在编译时就实例化好的,而泛型是在运行时仍然是泛型的;
  2. 模版支持特化、非类型模板参数和模版参数等,而泛型不支持,要简单的多;
  3. 泛型类型不能从类型参数继承,而模板可以;
  4. 泛型不支持元编程;
  5. 泛型类型支持类型参数约束,模板不支持。

托管数组

与C++不同,托管数组直接分配到堆上,首gc的管理,而且索引不再制定从某个地址偏移。并且要用Array关键字来声明。

array<int>^ arr1;
array<IntVal^, 2>^ arr2;//2维数组
//初始化
array<int>^ arr1 = gcnew array<int>(3) { 1, 2, 3 };
array<int>^ arr2 = gcnew array<int> {1, 2, 3};
array<int>^ arr3 =  {1,2,3};

对于引用类型的数组,实际上是句柄的数组。例如main函数int main(array<System::String^>^ args),实际上是String的句柄数组。另外.net提供了for each循环来遍历数组,与C#一样任何实现了IEnumberator接口的集合都可以使用for each

array<int>^ arr3 =  {1,2,3};

for each (int s in arr3)
{
	Console::WriteLine(s);
}

多维数组

与C++不同,多维数组的维数要在尖括号中定义,且读取多维数组也要在一个方括号中添加索引。

array<int, 2>^ array2d = gcnew array<int, 2>(3, 3);
array2d[1, 2] = 3;
array<int, 2>^ array2d_1 = {
	{1,2,3},
	{4,5,6},
	{7,8,9}
};


Console::WriteLine(array2d_1[0,1]);

List<T>

在实际开发过程中,更多的使用泛型集合类,因为集合可以改变大小。

using namespace System::Collections::Generic;

List<int>^ lst = gcnew List<int>();
lst->Add(0);
lst->Add(1);
lst->Add(2);
List<int>^ lst = gcnew List<int>(10);//指定容量

SortedList<String^, int>^ sl = gcnew SortedList<String^, int>();
sl->Add("a", 1044);

STL/CLR

​ STL容器是标准C++一部分,提供了一系列高性能、可扩展的集合类。C++/CLi提供了托管STL版本。使用方法与STL类似。

#include <cliext/vector>
using namespace System;
using namespace cliext;


int main(array<System::String^>^ args)
{
	vector<double> v1;

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i * 2);
	}
	for (vector<double>::iterator it = v1.begin();it!=v1.end(); it++)
	{
		Console::WriteLine(*it);
	}
	Console::WriteLine("程序结束");
}

image-20240104135206092

属性

在.net中一般不会公开字段,而是公开属性。属性本身就是方法包含get和set。在C++/CLI中支持两种属性,标准量属性和索引属性。

标量属性

标量属性也就是最常见的属性,将私有字段使用属性保护起来,使用property来声明,而且可以根据需要只实现get以满足只读属性的要求。

ref class Person
{
public:
	property String^ Name
	{
		String^ get()
		{
			return name;
		}
		void set(String^ value)
		{
			name = value;
		}
	}
	property int Age
	{
		int get()
		{
			return age;
		}
		void set(int value)
		{
			age = value;
		}
	}
private:
	String^ name;
	int age;
};


int main(array<System::String^>^ args)
{
	Person^ p = gcnew Person();
	p->Name = "小明";
	p->Age = 10;
	Console::WriteLine("{0}今年{1}岁", p->Name, p->Age);
	Console::WriteLine("程序结束");
}

image-20240104140941881

自动属性

在C#中是可以自动实现属性的如public int Order { set; get; } ,C++/CLI中同样可以:property String^ Name

属性继承

因为属性本质上就是方法,所以可以实现虚属性,以达到重写属性的目的。

public ref class Shape abstract
{
public:
	virtual property double Area;
};


public ref class Circle:Shape
{
private:
	double r=1;
public:
	virtual property double Area {
		double get() override 
		{
			return Math::PI * r * r;
		}
	}
};

属性索引

属性索引就是可以在对象上直接使用[]来访问,其工作方式与标量属性相似,只需要在属性名后面的方括中包含索引类型就可以

property double Name[int],这段代码定义的索引属性为Name,其索引类型为long,在get和set函数中的第一个参数必须为索引。

property double Name[int]
{
    double get(int idx){...}
    void set(int idx,double vlaue){...}
}

double bal = a1->Name[10];//使用

如果使用defaut名称,可以在对象上直接访问

ref class Account
{
private:
	List<int>^ lst = gcnew List<int>();
public:
	Account()
	{
		lst->Add(1);
		lst->Add(2);
		lst->Add(3);
		lst->Add(4);
		lst->Add(5);
		lst->Add(6);
	}
	property int Value[int]
	{
		int get(int idx)
		{
			return lst[idx];
		}
	}
    //使用default可以在对象上直接访问
	property int default[int]
	{
		int get(int idx)
		{
			return lst[idx];
		}
	}
};

int main(array<System::String^>^ args)
{
	Account^ a = gcnew Account();
	int s = a->Value[0];
	int ss = a[1];//使用default可以在对象上直接访问
	Console::WriteLine(s);
	Console::WriteLine(ss);
	Console::WriteLine("程序结束");
}

image-20240104152137180

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

步、步、为营

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值