我有两个矩阵类,一个用于CPU,一个用于GPU,分别说MatrixCudaMatrix。声明和定义在文件.h.cpp.cuh.cu中。在main中,我有

Matrix<int2_>      foo1(1,2);
// Definition of the elements of foo1...
CudaMatrix<int2_>  foo2(1,2);

cout << typeid(foo1).name() << "\n";
cout << typeid(foo2).name() << "\n";

// Equality
foo2=foo1;

现在,我在operator=CudaMatrix之间没有Matrix重载,但是我有以下operator=重载
const CudaMatrix& operator=(const CudaMatrix<LibraryNameSpace::int2_>&);

在两个CudaMatrix之间。发生了以下情况:
  • 两个typeid返回正确的foo1foo2类;
  • 上面的operator=重载在运行时针对foo2=foo1分配进行编译和调用。相反,我本来期望编译错误。
  • 分配结果导致foo2的结果正确!

  • 我正在使用Visual Studio 2010并以 Release模式进行编译。

    任何人都有暗示为什么会出现这种明显的非逻辑行为?

    谢谢。

    最佳答案

    它们之所以起作用的关键是因为您同时具有复制构造函数和显式复制赋值运算符。这两件事共同构成了看似未定义的case函数。因此,当您执行此操作时:

    Matrix<int2_>      foo1(1,2);
    CudaMatrix<int2_>  foo2(1,2);
    
    foo2 = foo1;
    

    发生的情况与此等效:
    Matrix<int2_>      foo1(1,2);
    CudaMatrix<int2_>  foo2(1,2);
    
    // foo2 = foo1;
    {
        CudaMatrix<int2_> x(foo1); // copy constructor
        foo2 = x; // Copy assignment
    }
    

    请注意,您在这里需要注意一些有关设备内存使用的含义(例如,两个设备内存分配和两组您在后台使用的API调用)。

    值得指出的是这不是CUDA特定的,它是C++ 98对象模型的标准功能。如果您想了解更多关于它如何工作以及为什么工作的信息(以及为什么看起来类似的反例不起作用),则可以从修改rule of three中受益。

    09-27 08:51
    查看更多