1

我用一个模板定义了一个类,该模板定义了一个通用数组类型 T 元素个数 N。我有另一个类,它有一个该数组的实例作为成员。当我尝试使用 setString 函数时,我传递的数组从 15 个元素任意变为 4 个元素。

// testClassArraySize.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <istream>
#include <ostream>
using namespace std;

template<class T, int N>
class CArray {
public:
    T arr[N];
    CArray(void) {/*arr=(T *)malloc(sizeof(T)*N);*/
        if (arr == NULL) {
            cout << "allocation error\n";
        }
    }
    ;
    //CArray (int n) {arr=new T [n]; if(arr==NULL){exit(0); cout<<"allocation error\n";}};
    CArray operator=(const T *);
    T operator[](const int i) {
        return arr[i];
    }
    ;
};

template<class T, int N>
CArray<T, N> CArray<T, N>::operator=(const T *srce) {
    size_t x = sizeof(arr);
    size_t y = sizeof(srce);
    for (int j = 0; j < sizeof(arr); j++) {
        if (j > sizeof(srce)) {
            arr[j] = 0;
            break;
        }
        arr[j] = srce[j];
    }
    return *this;
}

class myTestClass {
private:
    CArray<char, 15> myString;
public:
    myTestClass setString(char set[15]) {
        myString = set;
        size_t x = sizeof(set);
        return *this;
    }
    ;
};

int main() {
    myTestClass myObject;
    myObject.setString("helloWorld");
    return 0;
}

有谁知道为什么?

4

1 回答 1

2

这有几个问题,但你可能会看到的一个是线

CArray<T, N> CArray<T, N>::operator= (const T *srce)

注意:const T* source是指针,因此sizeof(srce)是指针的大小。我猜你使用的是32位系统?

sizeof为您提供对象的大小(即“存储区域”)。对于数组,这是整个数组的大小(以字节为单位)。sizeof( int[10] ) == sizeof(int) * 10. 指针本身就是一个对象,其大小取决于 C++ 实现(操作系统、编译器等)。在 32 位系统上,它通常是 4 字节。sizeof( char* )因此是 4 字节,而不是您传递给函数的数组的长度,sizeof( (char*)(char[10]) )仍然是 4 字节,而不是 10。

您可能会看到的另一个问题(但只能通过调试/跟踪)是setString(char set[15])已解决为setString(char* set). 因此x = sizeof(set)解析到x = sizeof(char*)通常是 4。

您将“helloWorld”传递给setString,它需要一个15 项的 char 数组char*;我会说这不是一个好主意,因为“helloWorld”有类型char const[10](注意const)。获取 15 字符数组的正确语法是char (&set)[15].

如果你添加一个模板成员函数,你可以更优雅地做到这一点:

// in class CArray
template < std::size_t length >
CArray& operator= (const T (&srce)[length]);    // note I return a reference, so no copying

这样,您将获得数组大小作为模板参数。注意:由于我const T在赋值操作中使用了此处,因此您还需要在setString.

template < class T, int N >
template < std::size_t srce_length >
CArray < T, N >& CArray < T, N > :: operator= (const T (&srce)[srce_length])
{
    for (int j = 0; j < N; j++) {    // N is the own length
        if (j >= srce_length) {    // note the >= instead of >, and srce_length instead of sizeof
            arr[j] = 0;
            break;
        }
        arr[j] = srce[j];
    }
    return *this;
}
于 2012-10-07T16:37:27.690 回答