1

假设我有一堂课:

class A
{
  private:
    const int * const v;
  public:
    A();
}

我想v在初始化列表中分配,我想我可以定义如下构造函数:

A::A():v((int*)malloc(10*sizeof(int))){}

但是,v 必须以非标准方式分配,如下所示:

cudaMalloc(&v,10*sizeof(int));

注意cudaMalloc是用于分配 GPU 内存的 CUDA API。

4

2 回答 2

8

(忽略整体设计、异常安全等大局问题,只关注最狭窄范围内的问题)

放弃在初始化列表中做的想法,而是在构造函数体中做

A::A() : v(NULL)
{
  cudaMalloc(&v, 10 * sizeof(int));
}

或者,或者,将分配函数包装到您自己的返回指针的函数中

void *wrapped_cudaMalloc(size_t size)
{
  void *m = NULL;
  cudaMalloc(&m, size);
  return m;
}
...

A::A() : v(wrapped_cudaMalloc(10 * sizeof(int)))
  {}

只是为了完整起见,在初始化列表中还有一种丑陋的复杂方式来完成它,而无需通过利用,operator的属性来创建任何包装器

A::A() : v((cudaMalloc(&v, 10 * sizeof(int)), v))
  {}

注意逗号表达式周围的附加对(),这是满足初始化语法所必需的(否则,将被视为参数分隔符而不是逗号运算符)。

于 2013-05-23T23:08:38.283 回答
3

除了 AndreyT 的出色帖子(以及他对逗号运算符的创造性使用)之外,您还可以这样总结:

class cudaMallocedInt
{
private:
    int *v;

public:
    cudaMallocedInt(int n)
    {
        cudaMalloc(&v, n * sizeof(int));
    }

    cudaMallocedInt(const cudaMallocedInt &o)
    {  
        // Do whatever is appropriate here. Probably some sort of dance.
    }

    ~cudaMallocedInt()
    {
        // Remember to cudaFree or whatever
    }

    operator int*()
    {
        return v;
    }
};

class A
{
private:
    cudaMallocedInt v;

public:
    A()
        : v(10)
    {
    }

    ...
};

更新:正如Johnsyweb在评论中指出的那样,请务必遵守三原则,以确保事情不会顺利进行,并且您会浪费您的周末来努力调试错误,而不是享受乐趣!

于 2013-05-23T23:18:47.823 回答