2010-11-24 98 views

回答

54

int* test();

,但是这将是 “多C++” 使用向量:

std::vector<int> test();

编辑
我 会澄清一些问题。由于您提到了C++,因此我将使用new[]delete[]运算符,但它与malloc/free一样。

在第一种情况下,你会写类似:

int* test() { 
    return new int[size_needed]; 
} 

,但它不是一个不错的主意,因为你的函数的客户端并不真的知道自己在返回数组的大小,虽然客户端可以通过致电delete[]安全地释放它。

int* theArray = test(); 
for (size_t i; i < ???; ++i) { // I don't know what is the array size! 
    // ... 
} 
delete[] theArray; // ok. 

更好的签名会是这样:

int* test(size_t& arraySize) { 
    array_size = 10; 
    return new int[array_size]; 
} 

而且你的客户端代码现在将是:

size_t theSize = 0; 
int* theArray = test(theSize); 
for (size_t i; i < theSize; ++i) { // now I can safely iterate the array 
    // ... 
} 
delete[] theArray; // still ok. 

由于这是C++,`的std :: vector的< T>是一种广泛使用的解决方案:

std::vector<int> test() { 
    std::vector<int> vector(10); 
    return vector; 
} 

现在,你不必叫delete[],因为它会通过对象来处理,你可以安全地遍历它:

std::vector<int> v = test(); 
std::vector<int>::iterator it = v.begin(); 
for (; it != v.end(); ++it) { 
    // do your things 
} 

哪一个更容易,更安全。

+2

我与返回'的std :: VECTOR`去。 – 2010-11-24 08:08:54

+8

个人而言,我认为如果你不解释它实际上没有返回一个数组,那么回答`int * test();`回答'如何在C++方法中返回一个数组?'[误]但是一个指针。 – 2010-11-24 09:53:41

2

那么如果你想从函数中返回你的数组,你必须确保这些值不会被存储在堆栈上,因为当你离开函数时它们将会消失。因此,要么让你的数组是静态的,要么分配内存(或者将它传入,但是你的初始尝试是用一个void参数)。对于你的方法我定义它是这样的:

int *gnabber(){ 
    static int foo[] = {1,2,3} 
    return foo; 
} 
16

我怎样才能返回一个C++方法的阵列,以及如何我必须声明呢? int [] test(void); ??

这听起来像一个简单的问题,但在C++中有很多选项。首先,你应该更喜欢......

  • std::vector<>,其动态地增长到在运行时遇到然而,许多元件,或

  • std::array<>(导入有C++ 11),它总是存储在编译时所指定的数量的元素,

...因为他们为您管理内存,以确保正确的行为,并大大简化了的东西:

std::vector<int> fn() 
{ 
    std::vector<int> x; 
    x.push_back(10); 
    return x; 
} 

std::array<int, 2> fn2() // C++11 
{ 
    return {3, 4}; 
} 

void caller() 
{ 
    std::vector<int> a = fn(); 
    const std::vector<int>& b = fn(); // extend lifetime but read-only 
             // b valid until scope exit/return 

    std::array<int, 2> c = fn2(); 
    const std::array<int, 2>& d = fn2(); 
} 

创建const引用返回数据的做法有时可以避免复制,但通常您可以只依赖返回值优化,或者 - 对于vector而不是array - 移动语义(随C++ 11引入) 。

如果你真的想用一个内置阵列(区别于所谓array标准库类上面提到的),一个办法是调用者预留空间,并告诉该函数使用它:

void fn(int x[], int n) 
{ 
    for (int i = 0; i < n; ++i) 
     x[i] = n; 
} 

void caller() 
{ 
    // local space on the stack - destroyed when caller() returns 
    int x[10]; 
    fn(x, sizeof x/sizeof x[0]); 

    // or, use the heap, lives until delete[](p) called... 
    int* p = new int[10]; 
    fn(p, 10); 
} 

另一种选择是包装在一个结构数组,这 - 不同于原阵列 - 都是合法的值从函数返回:

struct X 
{ 
    int x[10]; 
}; 

X fn() 
{ 
    X x; 
    x.x[0] = 10; 
    // ... 
    return x; 
} 

void caller() 
{ 
    X x = fn(); 
} 

与上面的开始,如果你使用的卡C++ 03你可能想把它推广到的东西更接近C++ 11 std::array

int* fn() 
{ 
    int* p = new int[2]; 
    p[0] = 0; 
    p[1] = 1; 
    return p; 
} 

void caller() 
{ 
    int* p = fn(); 
    // use p... 
    delete[] p; 
} 

要:

template <typename T, size_t N> 
struct array 
{ 
    T& operator[](size_t n) { return x[n]; } 
    const T& operator[](size_t n) const { return x[n]; } 
    size_t size() const { return N; } 
    // iterators, constructors etc.... 
    private: 
    T x[N]; 
}; 

另一种选择是有被调用函数在堆上分配内存有助于简化堆对象的管理,许多C++程序员使用“智能指针”来确保当指向对象的指针离开其作用域时删除。随着C++ 11:

std::shared_ptr<int> p(new int[2], [](int* p) { delete[] p; }); 
std::unique_ptr<int[]> p(new int[3]); 

如果你被困在C++ 03,最好的选择是看boost库可以在您的机器上:它提供boost::shared_array

还有一种选择是有一些由fn()保留的静态内存,虽然这不是线程安全的,并且意味着每次调用fn()都会覆盖任何人看到以前调用的指针。也就是说,简单的单线程代码可以方便(快速)。

int* fn(int n) 
{ 
    static int x[2]; // clobbered by each call to fn() 
    x[0] = n; 
    x[1] = n + 1; 
    return x; // every call to fn() returns a pointer to the same static x memory 
} 

void caller() 
{ 
    int* p = fn(3); 
    // use p, hoping no other thread calls fn() meanwhile and clobbers the values... 
    // no clean up necessary... 
} 
9

无法从C++函数返回数组。 8.3.5 [dcl.fct]/6:

功能不应有类型的阵列或函数的返回类型[...]

最常选择的替代方案是,返回的值该类包含数组的类类型,例如

struct ArrayHolder 
{ 
    int array[10]; 
}; 

ArrayHolder test(); 

还是要返回一个指向静态或动态分配的数组的第一个元素,文档必须向用户表明他是否需要(如果有的话他应该怎么)解除分配数组返回指针指着。

E.g.

int* test2() 
{ 
    return new int[10]; 
} 

int* test3() 
{ 
    static int array[10]; 
    return array; 
} 

虽然可以参考或返回一个指针数组,这是极其罕见的,因为它是没有实际优点的更复杂的语法在任何上述方法。

int (&test4())[10] 
{ 
     static int array[10]; 
     return array; 
} 

int (*test5())[10] 
{ 
     static int array[10]; 
     return &array; 
} 
-1

“我怎样才能在一个C返回一个阵列++方法和如何必须我声明它 INT []试验(无效);???”

template <class X> 
    class Array 
{ 
    X  *m_data; 
    int m_size; 
public: 
    // there constructor, destructor, some methods 
    int Get(X* &_null_pointer) 
    { 
     if(!_null_pointer) 
     { 
      _null_pointer = new X [m_size]; 
      memcpy(_null_pointer, m_data, m_size * sizeof(X)); 
      return m_size; 
     } 
     return 0; 
    } 
}; 

只是INT

class IntArray 
{ 
    int *m_data; 
    int m_size; 
public: 
    // there constructor, destructor, some methods 
    int Get(int* &_null_pointer) 
    { 
     if(!_null_pointer) 
     { 
      _null_pointer = new int [m_size]; 
      memcpy(_null_pointer, m_data, m_size * sizeof(int)); 
      return m_size; 
     } 
     return 0; 
    } 
}; 

例如

Array<float> array; 
float *n_data = NULL; 
int  data_size; 
if(data_size = array.Get(n_data)) 
{  // work with array } 

delete [] n_data; 

例如对于int

IntArray array; 
int  *n_data = NULL; 
int  data_size; 
if(data_size = array.Get(n_data)) 
{ // work with array } 

delete [] n_data;