在项目过程中,因为涉及到用c#调用c++的dll,其中有一个定义好的数组,想转为c++中的vector,将数组作为形参传到函数内部后,需要遍历每个数组,代码如下:
可以看到,在函数内部需要知道数组的长度,也就是元素个数,但使用了网上说的sizeof函数,始终求出来等于8,仔细查阅资料才发现这里存在一个数组作为函数参数的退化问题。即当数组被初始化后,在不被函数调用的情况下,可以用sizeof求出正确的数组长度,一旦作为函数参数传递到函数内部,该参数就退化为一个指针,对该指针求sizeof则始终是一个指针的长度,而不是数组的长度(我能吐槽这个奇葩的隐含规则么?这对于代码重构可是一个灾难性的后果)
对于c++老手高手高高手来说,这可能是一个基础性的常识问题,但对于新人来讲,绝对会发出“人生苦短,远离c渣渣”的感叹。幸好网友的智慧是无穷的,随手一查,就发现很多高手已经给出了解决方案。
1、把数组长度作为另外一个参数传进去。(好吧,也就多一个参数不是么)
2、自定义数组模板。(既然需要造轮子,那就只好造一个了),具体如下:
参考网友gaopengtttt的文章:C++ 简单实现数组类泛型编程示例
- 模板类实现:
- /*************************************************************************
- > File Name: arra.cpp
- > Author: gaopeng QQ:22389860 all right reserved
- > Mail: gaopp_200217@163.com
- > Created Time: Mon 10 Apr 2017 08:28:01 AM CST
- ************************************************************************/
- #include<iostream>
- #include <stdlib.h>
- #include <string.h>
- using namespace std;
- template <typename T>
- class myarray
- {
- private:
- T* array;
- unsigned int lenth;
- public:
- myarray();
- myarray(unsigned int len);
- myarray(const myarray& a);
- myarray& operator=(const myarray& b);
- T& operator[](int ind);
- ~myarray();
- };
- template <typename T>
- myarray<T>::~myarray()
- {
- if(this->array != NULL)
- {
- delete [] this->array;
- this->array = NULL;
- }
- }
- template <typename T>
- myarray<T>::myarray()
- {
- this->array = NULL;
- this->lenth = 0;
- }
- template <typename T>
- myarray<T>::myarray(unsigned int len)
- {
- this->array = new T[len];
- this->lenth = len;
- memset(this->array,0,sizeof(T)*len);
- }
- template <typename T>
- myarray<T>::myarray(const myarray<T>& a)
- {
- int i;
- this->lenth = a.lenth;
- this->array = new T[a.lenth];
- memset(this->array,0,sizeof(T)*a.lenth);
- for(i=0;i<a.lenth;i++)
- {
- *(this->array+i) = *(a.array+i);
- }
- }
- template <typename T>
- myarray<T>& myarray<T>::operator=(const myarray<T>& a)
- {
- if(this->array != NULL)
- {
- delete [] this->array;//调用类的析构函数不能用free
- this->array = NULL;
- }
- this->array = new T[a.lenth];
- this->lenth = a.lenth;
- for(int i=0;i<a.lenth;i++)
- {
- *(this->array+i) = *(a.array+i);//元素对象复制调用对象的=操作符重载
- }
- return *this;
- }
- template <typename T>
- T& myarray<T>::operator[](int ind)
- {
- if(ind>=this->lenth)
- {
- exit(10);
- }
- return *(this->array+ind);
- }
- 测试
- /*************************************************************************
- > File Name: main.cpp
- > Author: gaopeng QQ:22389860 all right reserved
- > Mail: gaopp_200217@163.com
- > Created Time: Mon 10 Apr 2017 08:31:57 AM CST
- ************************************************************************/
- #include<iostream>
- #include<stdlib.h>
- #include<string.h>
- #include"arra.cpp"
- using namespace std;
- class test
- {
- private:
- int a;
- int b;
- char* myc;
- public:
- test()
- {
- a = 0;
- b = 0;
- myc = NULL;
- }
- test(const test& a)
- {
- this->a = a.a;
- this->b = a.b;
- this->myc = (char*)calloc(strlen(a.myc)+1,0);
- strcpy(this->myc,a.myc);
- }
- friend ostream& operator<<(ostream& out,test& a)
- {
- out<<a.a<<endl;
- out<<a.b<<endl;
- cout<<a.myc;
- return out;
- }
- ~test()
- {
- if(myc != NULL)
- {
- free(myc);
- myc = NULL;
- }
- }
- test& operator=(const test& a)
- {
- if(this->myc != NULL)
- {
- free(this->myc);
- this->myc = NULL;
- }
- this->a = a.a;
- this->b = a.b;
- this->myc = (char*)calloc(strlen(a.myc)+1,0);
- strcpy(this->myc,a.myc);
- return *this;
- }
- test& operator=(const char* a)
- {
- if(this->myc != NULL)
- {
- free(this->myc);
- this->myc = NULL;
- }
- if(a == NULL)
- {
- this->myc = (char*)calloc(1,0);
- return *this;
- }
- this->myc = (char*)calloc(strlen(a)+1,0);
- strcpy(this->myc,a);
- return *this;
- }
- };
- int main()
- {
- myarray<test> a(3); //测试class类数组
- a[0] = "asdasd";
- a[1] = "test";
- a[2] = "kkkk";
- myarray<int> b(3); //测试int数组
- b[0] = 1;
- b[1] = 2;
- b[2] = 3;
- myarray<char> c(3); //测试char数组
- c[0] = 'a';
- c[1] = 'b';
- c[2] = 'c';
- myarray<test> d = a;//测试myarray拷贝构造函数
- for(int i=0;i<3;i++)
- {
- cout<<a[i]<<endl;
- cout<<d[i]<<endl;
- }
- for(int i=0;i<3;i++)
- {
- cout<<b[i]<<endl;
- }
- for(int i=0;i<3;i++)
- {
- cout<<c[i]<<endl;
- }
- }